2014-11-04 23 views
5

z Perl można sprawdzić, czy tablica zawiera wartośćSprawdź, czy tablica zawiera wartości

$ perl -e '@foo=(444,555,666); print 555 ~~ @foo ? "T" : "F"' 
T 

Jednak z awk, to podobna komenda sprawdza indeksy tablicy zamiast wartości

$ awk 'BEGIN {split("444 555 666", foo); print 555 in foo ? "T" : "F"}' 
F 

Jak czy mogę sprawdzić, czy tablica zawiera konkretną wartość w awk?

+1

wierzę jedyną opcją jest do pętli. –

+3

Tak jak mówi Etan, potrzebujesz pętli for. Możesz osiągnąć nieco elastyczny wynik, tworząc nową tablicę (hash) z wartościami jako klucze, np .: 'awk 'BEGIN {split (" 444 555 666 ", foo); dla (i = 1; i <= długość (foo); i ++) bar [foo [i]]; wydrukować 555 w takcie? "T": "F"} "' – Thor

+2

@ Thor - Nie możesz po prostu użyć 'for (i in foo) bar [foo [i]]' zamiast? – n0741337

Odpowiedz

3

podstawie Thor’s comment, funkcja ta wystarcza dla mnie:

function smartmatch(diamond, rough, x, y) { 
    for (x in rough) y[rough[x]] 
    return diamond in y 
} 
BEGIN { 
    split("444 555 666", z) 
    print smartmatch(555, z) ? "T" : "F" 
} 
6

awk Noob tutaj. Przetrawiłem Steven's answer i skończyłem z tym, mam nadzieję, łatwiejszym do zrozumienia fragmentem poniżej. Istnieją 2 bardziej subtelne problemy:

  • AWK tablica jest faktycznie słownikiem. To nie jest ["value1", "value2"], to bardziej jak {0: "value1", 1: "value2"}.
  • in sprawdza klucze i nie ma wbudowanego sposobu sprawdzania wartości.

Musisz więc przekonwertować tablicę (która jest w rzeczywistości słownikiem) do słownika z wartościami jako kluczami.

BEGIN { 

    split("value1 value2", valuesAsValues) 
    # valuesAsValues = {0: "value1", 1: "value2"} 

    for (i in valuesAsValues) valuesAsKeys[valuesAsValues[i]] = "" 
    # valuesAsKeys = {"value1": "", "value2": ""} 
} 

# Now you can use `in` 
($1 in valuesAsKeys) {print} 

Dla jednej wkładki:

echo "A:B:C:D:E:F" | tr ':' '\n' | \ 
awk 'BEGIN{ split("A D F", parts); for (i in parts) dict[parts[i]]=""} $1 in dict' 
Powiązane problemy