Usando 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
Este primero usa grep
para obtener las líneas de fileB.txt
que coincide exactamente con las líneas en fileA.txt
y genera los números de línea coincidentes junto con las propias líneas.
estoy usando -x
y -F
además de las opciones que se utilizan en la pregunta. Hago esto para evitar leer los patrones de fileA.txt
como expresiones regulares (-F
), y para hacer coincidir líneas completas, no subcadenas (-x
).
El datamash
La utilidad está analizando esto como líneas de :
-campos delimitados (-t :
), ordenándolo (-s
) en el segundo campo (-g 2
; los países) y colapsando el primer campo (collapse 1
; los números de línea) en una lista para cada país.
Entonces, obviamente, podría reemplazar los dos puntos y las comas con tabulaciones usando tr ':,' '\t\t'
, o con espacios de manera similar.
$ 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
Utilice awk
:
awk 'NR==FNR { country[$0]= country[$0]? country[$0] FS NR: NR; next }
($0 in country){ print $0, country[$0] }' fileB fileA
o para informar "recuento:0 " en caso de que hubiera un nombre de país en el archivo A que no aparece en el archivo B, haz lo siguiente:
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
Puede acoplar la salida de su comando grep con Miller (https://github.com/johnkerl/miller) y ejecutar
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
tendrás
Germany 4 9
USA 1 2 11
UK 5 6