Удаление похожих строк? - PullRequest
1 голос
/ 09 июля 2019

Я использовал это, чтобы удалить строки из первого файла, которые находятся во втором файле (разница).

awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file2.txt file1.txt >output.txt

Это прекрасно работает для линий, которые точно такие же, также быстро работает с файлами смиллионы строк.Теперь я наткнулся на ситуацию, когда у меня есть строки, которые похожи на строки в первом файле, но не совсем одинаковые, некоторые строки имеют 8-9 символов, добавленных в начале, но они одинаковы до конца строкиПримерно так:

file1

8952aa182685763d30758c730de536a9907f96e7
5e46468f50df8e410b0372dc8a550c0cec33d8bc
11111111-954f94fa00c220c40a49b37816c9146
5dd0a2058734e2c3e039f3a814fc86789474c65e
2222222-s54b2c1d6176b0aae91d85545670aa7a

file2

5e46468f50df8e410b0372dc8a550c0cec33d8bc
954f94fa00c220c40a49b37816c9146
s54b2c1d6176b0aae91d85545670aa7a

Требуемый результат:

8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e

Я пытался найти решение, но такПока не знаю, если у вас есть решение, которое уже было решено, поделитесь ссылкой, заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 09 июля 2019

Самый простой способ найти строки в file1 без частичного совпадения в file2:

grep -v -f file2 file1

Где вы используете инвертированное совпадение строк, перечисленных в file2, со строкамив file1 в результате:

8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e
3 голосов
/ 09 июля 2019

Я полагаю, что вам действительно нужно следующее:

$ awk -F'-' '(FNR==NR){a[$NF]; next}!($NF in a)' file2 file1

Это разбивает каждую строку на поля, разделенные -.Таким образом, для file1 значение $NF задается как

8952aa182685763d30758c730de536a9907f96e7 -> 8952aa182685763d30758c730de536a9907f96e7
5e46468f50df8e410b0372dc8a550c0cec33d8bc -> 5e46468f50df8e410b0372dc8a550c0cec33d8bc
11111111-954f94fa00c220c40a49b37816c9146 -> 954f94fa00c220c40a49b37816c9146
5dd0a2058734e2c3e039f3a814fc86789474c65e -> 5dd0a2058734e2c3e039f3a814fc86789474c65e
2222222-s54b2c1d6176b0aae91d85545670aa7a -> s54b2c1d6176b0aae91d85545670aa7a

Это именно та строка, которую вы хотите сопоставить с file2, на которую также ссылается $NF, поскольку она содержит одно поле.Это, однако, может быть проблематично, если в строках естественно больше дефисов.

Этот может быть лучше, чем решение grep, поскольку решение grep может удалять ложные срабатывания.Представьте себе строки в файле1, которые выглядят так:

xxs54b2c1d6176b0aae91d85545670aa7axxxxxx
yyys54b2c1d6176b0aae91d85545670aa7ayyyyy
zzzzs54b2c1d6176b0aae91d85545670aa7azzzz

Все они будут удалены.В приведенном выше случае это не так.

Вы также можете решить проблему по-другому, указав

Не показывать строки файла1, где находятся строкиfile2 соответствует концу соответствующей строки в line1.

Это можно решить с помощью awk следующим образом:

$ awk '(FNR==NR){a[$0]; next}
       {for(str in a) if (index($0,str)+length(str)-1==length($0)) print }' file2 file1

Мы могли бы использовать match вместо index, но match будет соответствовать шаблонам ERE, и если str содержит какие-либо специальные шаблоны ERE, он пропустит свое назначение.

...