2013-02-20 1 views
45

Viele Menschen in Prozess wurden durch die Veröffentlichung die folgende Lösung für AWK'ing mehr Input-Dateien auf einmal sehr hilfreich:AWK Mit Eingabe von mehreren Dateien

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

Dies funktioniert gut, aber ich habe mich gefragt, ob ich jemand könnte mir erklären warum? Ich finde die AWK-Syntax ein wenig schwierig, um den Dreh rauszukriegen, und hoffte, dass jemand nichts dagegen hätte, den Code-Ausschnitt für mich zu brechen.

Antwort

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

hier behandeln wir die 1. Eingabe (Datei2). sagen wir, FS ist Platz, wir bauen ein Array (a) auf, Index ist Spalte1, Wert ist column2 " " column3 die FNR==NR and next bedeutet, dieser Teil der Codes funktionieren nur für Datei2. Sie könnten Menschen gawk zu überprüfen, was NR und FNR

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

Wenn NR != FNR sind ist es Zeit, 2. Eingang zu verarbeiten, file1. Hier drucken wir die Zeile von Datei1 und nehmen Spalte1 als Index, um den Wert in array (a) auszudrucken. In einem anderen Wort sind Datei1 und Datei2 in beiden Dateien durch Spalte1 verbunden.

für NR und FNR, kurz,

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 

Sie sehen den Trick von FNR==NR überprüfen.

+0

Kent, ausgezeichnete Erklärung; vielen Dank. Ich war mir nicht bewusst, dass die "FNR == NR" eine Art "if" -Anweisung bildete. Das ist genau das, was ich brauche, um voranzukommen. Vielen Dank, dass Sie sich die Zeit genommen haben zu helfen! – jkovba

8

Ich habe diese Frage/Antwort bei Google gefunden und es scheint sich auf einen sehr spezifischen Datensatz in einer anderen Frage (How to merge two files using AWK?) zu beziehen. Was folgt, ist die Antwort, nach der ich gesucht habe (und die ich für die meisten Leute halten würde), d.h. einfach jede Zeile aus zwei verschiedenen Dateien mit AWK zu verketten. Obwohl Sie wahrscheinlich einige UNIX-Dienstprogramme wie beitreten oder Paste, AWK ist natürlich viel flexibler und leistungsfähiger, wenn Sie die gewünschte Ausgabe, anders nutzen könnte durch die Verwendung wenn Aussagen oder zur Änderung der OFS (was sein kann schwierig, abhängig von dem Programm zu tun, siehe unten), zum Beispiel der Ausgabe in eine viel ausdruck Weise (eine wichtige Überlegung für Shell scripters verändern)

für einfache Zeile-für-Zeile-Verkettung:

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

Dies emuliert die Funktion eines numerisch indizierten Arrays (AWK hat nur assoziative Arrays) durch Verwendung der impliziten Typkonvertierung. Es ist relativ ausdrucksstark und leicht zu verstehen.

Mit zwei Dateien test1 und test2 mit den folgenden Zeilen genannt:

test1:

line one 
line two 
line three 

test2:

line four 
line five 
line six 

ich dieses Ergebnis:

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

Abhängig von ho Wenn Sie die Werte zwischen den Spalten in der Ausgabe verbinden möchten, können Sie das entsprechende Ausgabefeldtrennzeichen auswählen. Hier ist ein Beispiel mit Ellipsen (...) Trennen der Spalten:

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

dieses Ergebnis Nachgeben:

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

ich zumindest hoffen, dass diese inspiriert Sie alle Vorteile der Kraft der AWK zu nehmen!

+4

Wenn das Ziel nur darin besteht, Spalten nebeneinander zu verbinden, ist es sehr einfach, den Befehl 'Einfügen' zu verwenden. – biocyberman