Mit GNU datamash
:
$ grep -n -x -F -f fileA.txt fileB.txt | datamash -s -t : -g 2 collapse 1
Germany:4,9
UK:5,6
USA:1,2,11
Dies verwendet zuerst grep
um die Zeilen von fileB.txt
zu erhalten das stimmt genau mit den Zeilen in fileA.txt
überein , und gibt die übereinstimmenden Zeilennummern zusammen mit den Zeilen selbst aus.
Ich verwende -x
und -F
zusätzlich zu den Optionen, die in der Frage verwendet werden. Ich mache das, um das Lesen der Muster aus fileA.txt
zu vermeiden als reguläre Ausdrücke (-F
) und um vollständige Zeilen abzugleichen, keine Teilstrings (-x
).
Die datamash
Das Dienstprogramm analysiert dies dann als Zeilen von :
-getrennte Felder (-t :
), sortieren (-s
) im zweiten Feld (-g 2
; die Länder) und das erste Feld einklappen (collapse 1
; die Zeilennummern) in eine Liste für jedes Land.
Sie könnten dann natürlich die Doppelpunkte und Kommas mit tr ':,' '\t\t'
durch Tabulatoren ersetzen , oder ähnlich mit Leerzeichen.
$ grep -n -x -f fileA.txt -F fileB.txt | datamash -s -t : -g 2 collapse 1 | tr ':,' '\t\t'
Germany 4 9
UK 5 6
USA 1 2 11
Verwenden Sie awk
:
awk 'NR==FNR { country[$0]= country[$0]? country[$0] FS NR: NR; next }
($0 in country){ print $0, country[$0] }' fileB fileA
oder um "count:0 zu melden " Falls in Datei A ein Ländername vorhanden war, der in Datei B nicht vorkommt, tun Sie Folgendes:
awk 'NR==FNR { country[$0]= country[$0]? country[$0] FS NR: NR; next }
($0 in country){ print $0, country[$0]; next } { print $0, "0" }' fileB fileA
Sie könnten Ihre grep-Befehlsausgabe mit Miller (https://github.com/johnkerl/miller) koppeln und ausführen
grep -nf fileA.txt fileB.txt | \
mlr --c2n --ifs ":" --implicit-csv-header --headerless-csv-output reorder -f 2 then \
nest --implode --values --across-records --nested-fs " " -f 1
Sie haben
Germany 4 9
USA 1 2 11
UK 5 6