Почему awk "не в" массиве работает как awk в массиве? - программирование
Подтвердить что ты не робот

Почему awk "не в" массиве работает как awk в массиве?

Здесь awk script, который пытается установить разницу двух файлов на основе их первого столбца:

BEGIN{
    OFS=FS="\t"
    file = ARGV[1]
    while (getline < file)
        Contained[$1] = $1
    delete ARGV[1]
    }
$1 not in Contained{
    print $0
}

Вот TestFileA:

cat
dog
frog

Вот TestFileB:

ee
cat
dog
frog

Однако, когда я запускаю следующую команду:

gawk -f Diff.awk TestFileA TestFileB

Я получаю вывод так, как если бы script содержал "in":

cat
dog
frog

Пока я не уверен, что "не в" является правильным синтаксисом для моего намерения, мне очень любопытно, почему он ведет себя точно так же, как когда я писал "in".

4b9b3361

Ответ 1

Я не могу найти doc о element not in array.

Попробуйте !(element in array).


Я думаю: awk видит not как неинициализированную переменную, поэтому not оценивается как пустая строка.

$1 not == $1 "" == $1

Ответ 2

Я понял это. (X in array) возвращает значение, поэтому для выполнения "не в массиве" вы должны это сделать:

if ( x in array == 0 )
   print "x is not in the array"

или в вашем примере:

($1 in Contained == 0){
   print $0
}

Ответ 3

Не уверен, что это похоже на то, что вы пытались сделать.

#! /bin/awk
# will read in the  second arg file and make a hash of the token
# found in column one. Then it will read the first arg file and print any
# lines with a token in column one not matching the tokens already defined
BEGIN{
    OFS=FS="\t"
    file = ARGV[1]
    while (getline  &lt file)
        Contained[$1] = $1
#    delete ARGV[1]  # I don't know what you were thinking here
#    for(i in Contained) {print Contained[i]} # debuging, not just for sadists
    close (ARGV[1])
}
{
   if ($1 in  Contained){} else { print $1 }
}

Ответ 4

В моем решении для этой проблемы я использую следующий оператор if-else:

if($1 in contained);else{print "Here goes your code for \"not in\""}