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 ( )awk
aufgeteilt wird (aber nicht in enthalten ist ) und ( ) vor dem Drucken angehängt wird).RS
$/
RS
$0
ORS
$\
-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.
awk
Eigentlich 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 join
im 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