Führen Sie Dateien mithilfe einer gemeinsamen Spalte zusammen

8

Ich habe zwei Dateien, aus denen ich eine dritte erstellen möchte, die alle Informationen enthält.

Datei 1:

a 111 
b 222 
c 333 
d 666 
e 777 

Datei 2:

111 x1  
222 x2
333 x3
444 x4 
555 x5 
666 x6 
777 x7 
888 x8

Ich möchte sie wie folgt kombinieren:

111  x1  a
222  x2  b
333  x3  c
444  x4  0
555  x5  0
666  x6  d
777  x7  e
888  x8  0

Hinweis:

Die zweite Spalte von Datei 1 ist eine Teilmenge der ersten Spalte von Datei 2

gforce89
quelle

Antworten:

7

Der joinBefehl macht fast das, was Sie brauchen, wenn die Dateien wie in Ihren Beispielen sortiert sind:

join -12 -a2 file1 file2 -o2.1,2.2,1.1

Sie müssen nur die Nullen zu den Zeilen ohne Übereinstimmung hinzufügen. Sie können den -eSchalter dafür verwenden:

join -12 -a2 file1 file2  -o2.1,2.2,1.1 -e0
Choroba
quelle
Wenn Sie das hinzufügen, -e0brauchen Sie kein Perl :)
LilloX
@LilloX: Stimmt, danke. Ich habe es versucht, bin aber gescheitert (Tippfehler).
Choroba
13

Verwenden von join:

join -1 1 -2 2 -a1 -e0 -o'0,1.2,2.1' file2 file1

Der Befehl join verbindet die Zeilen zweier Dateien, die ein gemeinsames Datenfeld verwenden. In diesem Fall: Verbinden Sie die Datei2 und die Datei1 mit dem Feld 1 ( -1 1) der Datei2 und dem Feld 2 ( -2 2) der Datei1.

Die Ausgabe lautet: "Verbundenes Feld, Feld 2 von Datei2, Feld 1 von Datei1" ( -o'0,1.2,2.1'), wenn ein Feld fehlt, setzen Sie 0 ( -e0)

Wenn eine der beiden Dateien mehr Datensätze enthält, fügen Sie diese hinzu (in diesem Fall file2) ( -a1)

Bitte beziehen Sie sich auf die Manpage des Befehls join

LilloX
quelle
Gut. Könnten Sie eine Erklärung hinzufügen?
Lety
Sicher, aktualisiert :)
LilloX
5

Ein bisschen awkMagie:

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0}; \
    printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}' \
    file1 file2

oder

awk 'FNR==NR{a[$2]=$1;next}{if(a[$1]==""){a[$1]=0};
    print $1,$2,a[$1]}' file1 file2

Ausgabe

111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Erläuterung

  • FNR==NR{a[$2]=$1;next}

    Läuft über file1( FNR==NR) und erstellt eine Schlüsselwertstruktur. Der Schlüssel ist die zweite Spalte ( $2) von file1, der Wert ist die erste Spalte ( $1) vonfile1

  • {if(a[$1]==""){a[$1]=0};print $1,$2,a[$1]}

    Läuft über file2und

    • if(a[$1]==""){a[$1]=0}

      Wenn der Schlüssel in der ersten Spalte ( $1) in file2nicht vorhanden ist file1, benötigen wir a0

    • print $1,$2,a[$1]

      Drucken (unter Verwendung print) der ersten und zweiten Spalte von file2und des Werts der Schlüsselwertstruktur mit dem Schlüssel der ersten Spalte ( $1) vonfile2

      oder

    • printf "%s%s%s%s%s\n",$1,FS,$2,FS,a[$1]}'

      Drucken (unter Verwendung printf) der ersten und zweiten Spalte von file2und des Werts der Schlüsselwertstruktur mit dem Schlüssel der ersten Spalte ( $1) von file2.

      • FS ist das Trennzeichen zwischen den Spalten aus der Eingabedatei

      • "%s%s%s%s%s\n"

        ist die Formatierung für die Ausgabe

        • %s - String

        • \n - Neue Zeile

AB
quelle
Könnten Sie den Code erklären?
Gforce89
Sicher, Antwort aktualisiert.
AB
1

Verwenden von q :

$ q "select f2.c1, f2.c2, ifnull(f1.c1,0) from file_2.txt f2 LEFT JOIN file_1.txt f1 on f1.c2 = f2.c1 "
111 x1 a
222 x2 b
333 x3 c
444 x4 0
555 x5 0
666 x6 d
777 x7 e
888 x8 0

Auf diese Weise kann es manchmal besser lesbar sein.

Vi.
quelle
1
Für alle, die sich fragen, qist im Paket python3-q-text-as-data(Python 3) und im Paket python-q-text-as-data(Python 2).
Kos
Danke, aber wo kann ich dieses qPaket bekommen? Ich scheine nicht in der Lage sein , zu installieren entweder python-q-text-as-dataoder python3-q-text-as-data. "E: Paket python3-q-text-as-data konnte nicht gefunden werden". Mein System bereits installiert python, python2.7, python3, und python3.4.
Paddy Landau
Möglicherweise ist das Paket zu neu und in Ihrer Distributionsversion nicht verfügbar. Sie können es klonen Github: github.com/harelba/q
Vi.