Verbinden Sie sieben Dateien mit awk Zeile für Zeile

Verbinden Sie sieben Dateien mit awk Zeile für Zeile

Ich habe sieben (oder acht usw.) Dateien mit der gleichen Zeilenanzahl.

Datei1

1.001
1.002
1.003
1.004

Datei2

2.001
2.002
2.003
2.004

Datei3

3.001
3.002
3.003
3.004

usw.

Gewünschte Ausgabe:

1.001;2.001;3.001;4.001;5.001;6.001;7.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004

Wie geht das mit einem kurzen Skript in Awk?

Antwort1

Wie steeldriver sagte, ist die sinnvollste Möglichkeit, dies zu tun, Folgendes paste:

$ paste -d';' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004

Wenn Sie jedoch Folgendes verwenden müssen awk:

$ awk '{a[FNR]=a[FNR](FNR==NR?"":";")$0} END{for (i=1;i<=FNR;i++) print a[i]}' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004

Das awk-Skript behält alle Daten im Speicher. Wenn die Dateien groß sind, könnte das ein Problem sein. Für diese Aufgabe pasteist es aber ohnehin besser und einfacher.

Wie es funktioniert

In diesem Skript aist ein Array mit a[i]die Ausgabe für Zeile i. Während wir jede der nachfolgenden Dateien durchlesen, hängen wir die neuen Informationen für Zeile ian das Ende von an a[i]. Nachdem wir mit dem Lesen der Dateien fertig sind, drucken wir die Werte in aus a. Genauer gesagt:

  • a[FNR]=a[FNR](FNR==NR?"":";")$0

    FNRist die Zeilennummer der aktuellen Datei, die wir lesen, und $0ist der Inhalt dieser Zeile. Dieser Code wird $0am Ende von angehängt a[FNR]. Außer wenn wir noch die erste Datei lesen, setzen wir vor ein Semikolon $0. Dies geschieht mit der komplex aussehenden ternären Anweisung: (FNR==NR?"":";"). Dies ist eigentlich nur ein if-then-else-Befehl. Wenn wir die erste Datei lesen, das heißt wenn FNR==NR, dann gibt es einen leeren String zurück "". Wenn nicht, gibt es ein Semikolon zurück, ;.

  • END{for (i=1;i<=FNR;i++) print a[i]}

    Nachdem wir mit dem Lesen aller Dateien fertig sind, werden die Daten ausgedruckt, die wir im Array gesammelt haben a.

Antwort2

POSIX Awk; das funktioniert mit einer beliebigen Anzahl von Dateien, und die Dateien müssen nicht einmal die gleiche Anzahl von Zeilen haben. Das Skript läuft weiter, bis alle Dateien keine Zeilen mehr haben:

BEGIN {
  do {
    br = ch = 0
    while (++ch < ARGC)
      if (getline < ARGV[ch]) {
        printf ch < ARGC - 1 ? $0 ";" : $0 RS
        br = 1
      }
  } while (br)
}

verwandte Informationen