Cosa è “NR == FNR” in awk?

Sto imparando il confronto dei file usando awk .

Ho trovato la syntax come di seguito,

 awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2 

Non riuscivo a capire qual è il significato di NR==FNR in questo? Se provo con FNR==NR allora ottengo lo stesso risultato?

Che cosa fa esattamente?

Cerca le chiavi (prima parola della linea) in file2 che si trovano anche in file1.
Passaggio 1: riempire l’array a con le prime parole del file 1:

 awk '{a[$1];}' file1 

Passaggio 2: Riempi l’array a e ignora il file 2 nello stesso comando. Per questo controlla il numero totale di record fino ad ora con il numero del file di input corrente.

 awk 'NR==FNR{a[$1]}' file1 file2 

Passaggio 3: Ignora le azioni che potrebbero venire dopo } durante l’analisi del file 1

 awk 'NR==FNR{a[$1];next}' file1 file2 

Passaggio 4: stampare la chiave di file2 quando viene trovata nell’array a

 awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2 

In awk, FNR riferisce al numero di record (tipicamente il numero di riga) nel file corrente e NR riferisce al numero di record totale. Ciò significa che la condizione NR==FNR è vera solo per il primo file, poiché FNR reimposta su 1 per la prima riga di ciascun file, ma NR continua ad aumentare.

Questo pattern viene in genere utilizzato per eseguire azioni solo sul primo file. Il next all’interno del blocco significa che tutti gli altri comandi vengono saltati, quindi vengono eseguiti solo su file diversi dal primo.

Non è chiaro il motivo per cui ci si aspetterebbe che FNR==NR sia diverso da NR==FNR .

Cerca NR e FNR nel manuale di awk e poi chiediti qual è la condizione in cui NR==FNR nel seguente esempio:

 $ 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 

Ci sono variabili integrate di awk .

NR – Fornisce il numero totale di record elaborati.

FNR – Fornisce il numero totale di record per ciascun file di input.

Supponendo di avere i file a.txt e b.txt con

 cat a.txt a b c d 1 3 5 cat b.txt a 1 2 6 7 

Tieni presente che NR e FNR sono variabili integrate di awk. NR – Fornisce il numero totale di record elaborati. (in questo caso sia in a.txt che in b.txt) FNR – Fornisce il numero totale di record per ogni file di input (registra in a.txt o 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 

aggiungiamo “next” per saltare il primo abbinato con NR == FNR

in b.txt e in 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 

in b.txt ma non in 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