Что такое "NR == FNR" в awk?
Я изучаю сравнение файлов с помощью awk
.
Я нашел синтаксис, как показано ниже,
awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2
Я не мог понять, что такое значение NR==FNR
в этом?
Если я попробую с FNR==NR
, то также получаю такой же результат?
Что именно он делает?
Ответы
Ответ 1
Ищите ключи (первое слово строки) в файле2, которые также находятся в файле1.
Шаг 1: заполнить массив a первыми словами файла 1:
awk '{a[$1];}' file1
Шаг 2: Заполните массив a и проигнорируйте файл 2 в той же команде. Для этого проверьте общее количество записей до сих пор с номером текущего входного файла.
awk 'NR==FNR{a[$1]}' file1 file2
Шаг 3. Игнорируйте действия, которые могут возникнуть после }
при анализе файла 1
awk 'NR==FNR{a[$1];next}' file1 file2
Шаг 4: напечатайте ключ файла2, найденный в массиве a
awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2
Ответ 2
В awk FNR
относится к номеру записи (обычно к номеру строки) в текущем файле, а NR
относится к общему количеству записей. Оператор ==
является оператором сравнения, который возвращает истину, когда два окружающих операнда равны.
Это означает, что условие NR==FNR
верно только для первого файла, поскольку FNR
сбрасывается до 1 для первой строки каждого файла, но NR
продолжает увеличиваться.
Этот шаблон обычно используется для выполнения действий только с первым файлом. next
внутри блока означает, что все дальнейшие команды пропускаются, поэтому они запускаются только для файлов, отличных от первой.
Условие FNR==NR
сравнивает те же два операнда, что и NR==FNR
, поэтому оно ведет себя одинаково.
Ответ 3
Посмотрите NR
и FNR
в руководстве awk, а затем спросите себя, каково условие, при котором NR==FNR
в следующем примере:
$ cat file1
a
b
c
$ cat file2
d
e
$ awk '{print FILENAME, NR, FNR, $0}' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e
Ответ 4
Существуют встроенные переменные awk
.
NR
- Он дает общее количество обработанных записей.
FNR
- Он дает общее количество записей для каждого входного файла.
Ответ 5
Предположим, что у вас есть файлы a.txt и b.txt с
cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7
Имейте в виду, что NR и FNR являются встроенными переменными awk. NR - Дает общее количество обработанных записей. (в этом случае как в файле.txt, так и в b.txt). FNR. Дает общее количество записей для каждого входного файла (записи в файле a.txt или b.txt)
awk 'NR==FNR{a[$0];}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
a.txt 1 1 a
a.txt 2 2 b
a.txt 3 3 c
a.txt 4 4 d
a.txt 5 5 1
a.txt 6 6 3
a.txt 7 7 5
b.txt 8 1 a
b.txt 9 2 1
позволяет добавить "следующий", чтобы пропустить первое совпадение с NR == FNR
в b.txt и в a.txt
awk 'NR==FNR{a[$0];next}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1
в b.txt, но не в a.txt
awk 'NR==FNR{a[$0];next}{if(!($0 in a))print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 10 3 2
b.txt 11 4 6
b.txt 12 5 7
awk 'NR==FNR{a[$0];next}!($0 in a)' a.txt b.txt
2
6
7