Utilisation de 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
Cela utilise d'abord grep
pour obtenir les lignes de fileB.txt
qui correspond exactement aux lignes de fileA.txt
, et génère les numéros de ligne correspondants avec les lignes elles-mêmes.
J'utilise -x
et -F
en plus des options utilisées dans la question. Je fais cela pour éviter de lire les modèles de fileA.txt
sous forme d'expressions régulières (-F
), et pour faire correspondre des lignes complètes, pas des sous-chaînes (-x
).
Le datamash
l'utilitaire analyse ensuite cela comme des lignes de :
-champs délimités (-t :
), en le triant (-s
) sur le deuxième champ (-g 2
; les pays) et en réduisant le premier champ (collapse 1
; les numéros de ligne) dans une liste pour chaque pays.
Vous pouvez alors évidemment remplacer les deux-points et les virgules par des tabulations en utilisant tr ':,' '\t\t'
, ou avec des espaces de la même manière.
$ 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
Utilisez awk
:
awk 'NR==FNR { country[$0]= country[$0]? country[$0] FS NR: NR; next }
($0 in country){ print $0, country[$0] }' fileB fileA
ou pour signaler "count :0 " au cas où il y aurait un countryName dans le fichierA qui n'apparaît pas dans le fichierB, faites :
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
Vous pouvez coupler la sortie de votre commande grep avec Miller (https://github.com/johnkerl/miller) et exécuter
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
Vous aurez
Germany 4 9
USA 1 2 11
UK 5 6