2013-02-20 9 views
45

molte persone sono state molto utili, pubblicando la seguente soluzione per AWK'ing più file di input in una sola volta:Utilizzando AWK per elaborare l'input da più file

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1 

Questo funziona bene, ma mi chiedevo se qualcuno potrebbe spiegarmi perché? Trovo che la sintassi AWK sia un po 'difficile da comprendere e speravo che a qualcuno non dispiacesse spezzare lo snippet di codice per me.

risposta

50
awk 'FNR==NR{a[$1]=$2 FS $3;next} 

qui viene gestito il primo ingresso (file2). per esempio, FS è spazio, costruiamo un array (a), indice è colonna1, il valore è column2 " " column3 il codice FNR==NR and next significa che questa parte di codici funziona solo per file2. si potrebbe l'uomo gawk verificare quali sono NR e FNR

{ print $0, a[$1]}' file2 file1 

Quando NR != FNR è il momento di elaborare 2 ° ingresso, file1. qui stampiamo la riga di file1 e prendiamo la colonna1 come indice, scopriamo il valore nella matrice (a) stampa. in un'altra parola, file1 e file2 sono uniti da column1 in entrambi i file.

per NR e FNR, a breve,

1st input has 5 lines 
2nd input has 10 lines, 

NR would be 1,2,3...15 
FNR would be 1...5 then 1...10 

si vede il trucco di FNR==NR controllo.

+0

Kent, spiegazione eccellente; Grazie mille. Non mi rendevo conto che il 'FNR == NR' stava formando un tipo di dichiarazione 'se'. Questo è esattamente ciò di cui ho bisogno per essere in grado di andare avanti. Grazie mille per il tempo di aiutare! – jkovba

8

Ho trovato questa domanda/risposta su Google e sembra riferirsi a un set di dati molto specifico trovato in un'altra domanda (How to merge two files using AWK?). Quello che segue è la risposta che stavo cercando (e che penso che la maggior parte delle persone sarebbe), cioè semplicemente per concatenare ogni riga da due file diversi usando AWK. Anche se probabilmente si potrebbe utilizzare alcune utility UNIX come uniscono o pasta, AWK è ovviamente molto più flessibile e potente se l'output desiderato è diverso, utilizzando se dichiarazioni, o alterare le OFS (che possono essere più difficile fare a seconda dell'utilità; vedi sotto) per esempio, alterando l'uscita in un modo molto più espressivo (una considerazione importante per scripters shell)

per semplice concatenazione riga per riga:

awk 'FNR==NR { a[FNR""] = $0; next } { print a[FNR""], $0 }' file1 file2.

Questo emula la funzione di una matrice indicizzata numericamente (AWK ha solo array associativi) utilizzando la conversione del tipo implicito. È relativamente espressivo e facile da capire.

Utilizzando due file chiamato test1 e test2 con le seguenti righe:

test1:

line one 
line two 
line three 

test2:

line four 
line five 
line six 

ottengo questo risultato:

line one line four 
line two line five 
line three line six 

A seconda di ho Se si desidera unire i valori tra le colonne nell'output, è possibile selezionare il separatore del campo di output appropriato. Ecco un esempio con ellissi (...) Che separa le colonne:

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 }' test1 test2

Cedendo questo risultato:

line one...line four 
line two...line five 
line three...line six 

Spero almeno che questa ispira tutti voi di sfruttare la potenza di AWK!

+4

Se l'obiettivo è solo quello di unire le colonne affiancate, è molto semplice usare il comando 'paste'. – biocyberman

Problemi correlati