Verbinden: Zwei Dateien - aber nur die letzten beiden Spalten anhängen

Verbinden: Zwei Dateien - aber nur die letzten beiden Spalten anhängen

Angesichts der Dateien:

1.txt

1, abc, 123, 456, 789
2, lmn, 123, 456, 789
3, pqr, 123, 456, 789

2.txt

1, abc, 123, 000, 000
3, lmn, 123, 000, 000
9, opq, 123, 000, 000  

OUTPUT.txt

ID, NAME, X,    1A,    1B,  2A,   2B   
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000 

Ich habe verwendetDasals Referenz.

Ich habe Folgendes versucht:

join -t , -a1 -a2 -1 1 -2 1 -o 0 -o 1.2 -o 1.3 -o 1.4 -o 1.5 -o 2.4 -o 2.5 -e "MISSING" 1.txt 2.txt

Das Ergebnis:

1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789,MISSING,MISSING
3, pqr, 123, 456, 789, 000, 000
9,MISSING,MISSING,MISSING,MISSING, 000, 000

Irgendeine Hilfe?

Antwort1

Ich glaube nicht, dass du das alleine schaffst join. Du könntest Folgendes tun:

join -t, -a1 -a2 -o0,1.2,1.3,1.4,1.5,2.2,2.3,2.4,2.5 -e MISSING 1.txt 2.txt |
  perl -F, -lape '@F[1..2]=@F[5..6] if $F[1] eq "MISSING";
                  $_=join",",@F[0..4],@F[7..8]'
  • -p: Verwenden Sie eine zeilenweise Leseschleife wie in sed/awk
  • -a, -F,: wie awk, die Zeilen in Felder (in das Array) aufteilen @F.
  • -l: arbeitet mit dem Inhalt von Zeilen (funktioniert wie wenn die Eingabe in ( ) awkaufgeteilt wird (aber nicht in enthalten ist ) und ( ) vor dem Drucken angehängt wird).RS$/RS$0ORS$\
  • -e ...: Perl-[Ausdruck, der für jede Zeile ausgewertet werden soll.
  • Dann liest es sich fast wie Englisch: Die Felder 1 bis 2 werden auf die Felder 5 bis 6 gesetzt, wenn Feld 1 (das zweite Feld, da die Indizes bei 0 beginnen) „FEHLT“. Dann wird der Inhalt des aktuellen Datensatzes ($_ ist wie $0 in awk) auf die Felder 0 bis 4 und 7 bis 8 gesetzt.

awkEigentlich ist es nicht komplizierter , dasselbe in folgendes zu schreiben :

awk -F, -vOFS=, '$2 == "MISSING"{$2=$6;$3=$7}
                 {print $1,$2,$3,$4,$5,$8,$9}'

Antwort2

nur mit awk:

awk -F, -v OFS=, '
    BEGIN {m = " MISSING"}

    # process file1
    NR == FNR {lines[$1] = $0; next} 

    # process file2
    {
        added[$1] = $4 OFS $5
        if (!($1 in lines)) {
            $4 = m
            $5 = m
            lines[$1] = $0
        }
    } 

    # print the combined output
    END {
        for (id in lines) {
            if (!(id in added)) 
                added[id] = m OFS m
            print lines[id], added[id]
        }
    }
' 1.txt 2.txt | sort -n
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000  

Antwort3

Klingt, als ob Sie die ersten drei Felder verknüpfen möchten. Anschließend sollten Sie die ersten beiden Trennzeichen joinim neuen ersten Feld ändern und dann die Trennzeichen wiederherstellen:

join -t, -j1 -a1 -a2 -o 0 1.2 1.3 2.2 2.3 -e " MISSING" \
<(sed 's/, /\x02/;s/, /\x02/' 1.txt) <(sed 's/, /\x02/;s/, /\x02/' 2.txt) \
| sed 's/\x02/, /g'

kehrt zurück

1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000

verwandte Informationen