Menggunakan 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
Ini pertama menggunakan grep
untuk mendapatkan baris dari fileB.txt
yang sama persis dengan baris di fileA.txt
, dan menampilkan nomor baris yang cocok bersama dengan baris itu sendiri.
Saya menggunakan -x
dan -F
selain pilihan yang digunakan dalam pertanyaan. Saya melakukan ini untuk menghindari membaca pola dari fileA.txt
sebagai ekspresi reguler (-F
), dan untuk mencocokkan baris lengkap, bukan substring (-x
).
datamash
utilitas kemudian mem-parsing ini sebagai baris :
-bidang yang dibatasi (-t :
), mengurutkannya (-s
) pada kolom kedua (-g 2
; negara) dan menciutkan kolom pertama (collapse 1
; nomor baris) ke dalam daftar untuk setiap negara.
Anda kemudian dapat dengan jelas mengganti titik dua dan koma dengan tab menggunakan tr ':,' '\t\t'
, atau dengan spasi dengan cara yang serupa.
$ 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
Gunakan awk
:
awk 'NR==FNR { country[$0]= country[$0]? country[$0] FS NR: NR; next }
($0 in country){ print $0, country[$0] }' fileB fileA
atau untuk melaporkan "jumlah:0 " seandainya ada CountryName di fileA yang tidak muncul di fileB, lakukan:
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
Anda dapat memasangkan keluaran perintah grep Anda dengan Miller (https://github.com/johnkerl/miller) dan menjalankan
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
Anda akan memiliki
Germany 4 9
USA 1 2 11
UK 5 6