Wie kann ich zwei Dateien A und B erhalten und ein Ergebnis wie das folgende ausgeben:
Datei A:
001 Apple, CA
020 Banana, CN
023 Apple, LA
045 Orange, TT
101 Orange, OS
200 Kiwi, AA
Datei B:
01-Dec-2013 01.664 001 AAA CAC 1083
01-Dec-2013 01.664 020 AAA CAC 0513
01-Dec-2013 01.668 023 AAA CAC 1091
01-Dec-2013 01.668 101 AAA CAC 0183
01-Dec-2013 01.674 200 AAA CAC 0918
01-Dec-2013 01.674 045 AAA CAC 0918
01-Dec-2013 01.664 001 AAA CAC 2573
01-Dec-2013 01.668 101 AAA CAC 1091
01-Dec-2013 01.668 020 AAA CAC 6571
01-Dec-2013 01.668 023 AAA CAC 2148
01-Dec-2013 01.674 200 AAA CAC 0918
01-Dec-2013 01.668 045 AAA CAC 5135
Ergebnis:
01-Dec-2013 01.664 001 AAA CAC 1083 Apple, CA
01-Dec-2013 01.664 020 AAA CAC 0513 Banana, CN
01-Dec-2013 01.668 023 AAA CAC 1091 Apple, LA
01-Dec-2013 01.668 101 AAA CAC 0183 Orange, OS
01-Dec-2013 01.674 200 AAA CAC 0918 Kiwi, AA
01-Dec-2013 01.674 045 AAA CAC 0918 Orange, TT
01-Dec-2013 01.664 001 AAA CAC 2573 Apple, CA
01-Dec-2013 01.668 101 AAA CAC 1091 Orange, OS
01-Dec-2013 01.668 020 AAA CAC 6571 Banana, CN
01-Dec-2013 01.668 023 AAA CAC 2148 Apple, LA
01-Dec-2013 01.674 200 AAA CAC 0918 Kiwi, AA
01-Dec-2013 01.668 045 AAA CAC 5135 Orange, TT
(Datei A: Die Nummer sollte mit der mittleren Nummer aus Datei B übereinstimmen.)
Gibt es eine Möglichkeit, dies zu tun?
awk
Antwort akzeptieren , sollten Sie das Bash-Script-Tag entfernen.Hier ist ein Bash-Skript, das genau das tut, wonach Sie suchen. Das Skript heißt
mergeAB.bash
.Wenn Sie es ausführen:
Einzelheiten
Das allererste, was wir tun, ist, den Befehl
readarray
zu verwenden, um den Inhalt vonfileA.txt
in ein Array einzulesen . Dies ist eine neuere Funktion von Bash 4.x. Wenn Sie also eine ältere Version von Bash verwenden, können Sie stattdessen Folgendes verwenden:Der Rest dieses Skripts ist etwas komplex, aber ich habe
echo
in der Mitte eine ausführliche Beschreibung hinterlassen , die Sie entfernen können, um zu sehen, was los ist.Was ist denn hier los? Es gibt einen Zähler, mit
$i
dem wir jede Zeile zählen,fileB.txt
während wir sie durchlaufen. Wir berechnen dann$idx
durch Berechnung der Modulo-Division des aktuellen Wertes von$i
und der Anzahl der Zeilen infileA.txt
.HINWEIS: Die Länge des Arrays
A
. Wenn$idx
wir auf diese Weise berechnen, können wir es von 0 bis 5, dann von 0 bis 5 usw. "schleifen" lassen. In der obigen Debug-Ausgabe können Sie dies mit derIDX:
Spalte sehen.Der Rest des Skripts ist ziemlich normal und verwendet
printf
das Drucken der verketteten Zeilen vonfileB.txt
mit der entsprechenden Zeile vonfileA.txt
.quelle
Ich vermute, dass das
awk
Konstrukt eleganter gemacht werden kann, aber es scheint zu funktionieren.quelle
Das
join
Dienstprogramm führt einen "Gleichheits-Join" für die angegebenen Dateien durch und schreibt das Ergebnis in die Standardausgabe. Das "Verknüpfungsfeld" ist das Feld in jeder Datei, mit dem die Dateien verglichen werden.Mit anderen Worten, Sie haben zwei Dateien, die eine Spalte gemeinsam nutzen. Sie können die Zeilen der Dateien verbinden, in denen die Spalte gleich ist.
Lass es uns versuchen:
Ja, funktioniert. Aber nicht in dem von Ihnen angegebenen Format. Tauschen wir also die Dateien aus:
Viel besser. Immer noch nicht ganz richtig, da das verbundene Feld zuerst angezeigt wird. Awk kann das beheben:
Hier bitteschön. Die Felder sind in derselben Reihenfolge. In können
awk
Sieprintf
einige Registerkarten verwenden oder einfügen, wenn Sie den genauen Abstand erhalten möchten, aber ich denke, Sie werden auf die Idee kommen.quelle
join
ordnungsgemäß funktionieren.join
ist auch nicht ganz richtig für die Frage. Es gibt mehr Zeilen von B als von A; join gibt nicht alle Zeilen aus. Und es zerstört die festen Feldbreiten (dh frisst Leerzeichen)join
ist definitiv das richtige Werkzeug für diesen Job :join -1 1 -2 3 -o 2.1 2.2 2.3 2.4 2.5 2.6 1.2 1.3 fileA <(sort -k3 fileB)
. Sie können sogar die Reihenfolge der ZeilenfileB
und den Abstand beibehalten, wenn Sie dies wünschen. Durchsuchen Sie meine Beiträge unter demjoin
Tag, wenn Sie neugierig sind, wie.join
ist ein schlechtes Werkzeug für die Aufgabe; Sie haben nichts anderes bewiesen.file1
ist bereits sortiert, obwohl im Allgemeinen beide sortiert werden müssen, also stimme ich hier voll und ganz zu. Die Tatsache, dasssort
"die Bestellung solide beendet", ist irrelevant, da Sie die Ausgabe auf die ursprüngliche Reihenfolge zurücksortieren können. Das heißt, wenn Sie klug genug sind. Ich habe nicht das Bedürfnis, Ihnen etwas zu beweisen, aber hier sind einige Beispiele, die Sie lesen können: 1 , 2 , 3 .Mit einem Array, wie angefordert (vollständig in
bash
) ...(funktioniert in bash v2)
Die erste Zeile lädt das Array "A" aus Datei A. Das 0x $ num- Bit dient dazu, alles in derselben Zahlenbasis zu halten, andernfalls werden sie durch die führenden Nullen oktal. Die zweite Zeile liest jede Zeile der Datei B (wobei Leerzeichen erhalten bleiben), legt die Positionsargumente aus dieser Zeile fest und druckt schließlich die Zeile plus den indizierten Eintrag von "A".
quelle