2014-11-04 4 views
5

С Perl вы можете проверить, если массив содержит значениеПроверьте массив содержит значение

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

Однако с AWK, эта подобная команда проверяет индексы массива, а не значений

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

Как могу ли я проверить, содержит ли массив определенное значение с awk?

+1

Я считаю, что единственным вариантом является цикл. –

+3

Как говорит Этан, вам нужна петля. Вы можете получить несколько гибкий результат, создав новый массив (хеш) со значениями в виде ключей, например: 'awk 'BEGIN {split (" 444 555 666 ", foo); for (i = 1; i <= length (foo); i ++) bar [foo [i]]; распечатать 555 в баре? "T": "F"} '' – Thor

+2

@Thor - Не можете ли вы просто использовать' for (i in foo) bar [foo [i]] 'вместо этого? – n0741337

ответ

3

на основе Thor’s comment, эта функция делает трюк для меня:

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 нуб здесь. Я переварил Steven's answer и закончил тем, что, надеюсь, будет легче понять фрагмент ниже. Есть еще две тонкие проблемы:

  • Awk array на самом деле словарь. Это не ["value1", "value2"], это больше похоже на {0: "value1", 1: "value2"}.
  • in проверяет ключи, и нет встроенного способа проверки значений.

Поэтому вам необходимо преобразовать свой массив (который на самом деле является словарем) в словарь со значениями в виде ключей.

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} 

Для однострочных:

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' 
Смежные вопросы