删除相似的行?
Deleting similar lines?
我一直在使用它来删除第一个文件中第二个文件中的行(差异)。
awk 'FNR==NR{a[[=10=]]++}FNR!=NR && !a[[=10=]]{print}' file2.txt file1.txt >output.txt
这对于完全相同的行非常有效,而且对于具有数百万行的文件也能快速处理。
现在,我偶然发现我的行与第一个文件中的行相似,但不完全相同,有些行在开头附加了 8-9 个字符,但直到行尾都是相同的,像这样:
文件 1
8952aa182685763d30758c730de536a9907f96e7
5e46468f50df8e410b0372dc8a550c0cec33d8bc
11111111-954f94fa00c220c40a49b37816c9146
5dd0a2058734e2c3e039f3a814fc86789474c65e
2222222-s54b2c1d6176b0aae91d85545670aa7a
文件 2
5e46468f50df8e410b0372dc8a550c0cec33d8bc
954f94fa00c220c40a49b37816c9146
s54b2c1d6176b0aae91d85545670aa7a
想要的结果:
8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e
我试图找到解决方案,但到目前为止我还没有找到,如果您有已经解决的解决方案,请分享一个 link,在此先感谢。
在 file2
中不部分匹配的情况下查找 file1
中的行的最简单方法是:
grep -v -f file2 file1
将 file2
中列出的那些行与 file1
中的行进行反向匹配,结果是:
8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e
我相信你真正想要的是:
$ 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 解决方案可能会消除误报。想象一下 file1 中的行看起来像:
xxs54b2c1d6176b0aae91d85545670aa7axxxxxx
yyys54b2c1d6176b0aae91d85545670aa7ayyyyy
zzzzs54b2c1d6176b0aae91d85545670aa7azzzz
所有这些都将被删除。在上述情况下,情况并非如此。
您也可以通过陈述
以不同方式解决问题
Don't show the lines of file1 where the lines of file2 match the end of the corresponding line in line1.
这可以通过以下方式用awk解决:
$ awk '(FNR==NR){a[[=13=]]; next}
{for(str in a) if (index([=13=],str)+length(str)-1==length([=13=])) print }' file2 file1
我们本可以使用 match
而不是 index
,但是 match
将匹配 ERE 模式,如果 str
包含任何特殊的 ERE 模式,它将无法达到目的.
我一直在使用它来删除第一个文件中第二个文件中的行(差异)。
awk 'FNR==NR{a[[=10=]]++}FNR!=NR && !a[[=10=]]{print}' file2.txt file1.txt >output.txt
这对于完全相同的行非常有效,而且对于具有数百万行的文件也能快速处理。 现在,我偶然发现我的行与第一个文件中的行相似,但不完全相同,有些行在开头附加了 8-9 个字符,但直到行尾都是相同的,像这样:
文件 1
8952aa182685763d30758c730de536a9907f96e7
5e46468f50df8e410b0372dc8a550c0cec33d8bc
11111111-954f94fa00c220c40a49b37816c9146
5dd0a2058734e2c3e039f3a814fc86789474c65e
2222222-s54b2c1d6176b0aae91d85545670aa7a
文件 2
5e46468f50df8e410b0372dc8a550c0cec33d8bc
954f94fa00c220c40a49b37816c9146
s54b2c1d6176b0aae91d85545670aa7a
想要的结果:
8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e
我试图找到解决方案,但到目前为止我还没有找到,如果您有已经解决的解决方案,请分享一个 link,在此先感谢。
在 file2
中不部分匹配的情况下查找 file1
中的行的最简单方法是:
grep -v -f file2 file1
将 file2
中列出的那些行与 file1
中的行进行反向匹配,结果是:
8952aa182685763d30758c730de536a9907f96e7
5dd0a2058734e2c3e039f3a814fc86789474c65e
我相信你真正想要的是:
$ 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 解决方案可能会消除误报。想象一下 file1 中的行看起来像:
xxs54b2c1d6176b0aae91d85545670aa7axxxxxx
yyys54b2c1d6176b0aae91d85545670aa7ayyyyy
zzzzs54b2c1d6176b0aae91d85545670aa7azzzz
所有这些都将被删除。在上述情况下,情况并非如此。
您也可以通过陈述
以不同方式解决问题Don't show the lines of file1 where the lines of file2 match the end of the corresponding line in line1.
这可以通过以下方式用awk解决:
$ awk '(FNR==NR){a[[=13=]]; next}
{for(str in a) if (index([=13=],str)+length(str)-1==length([=13=])) print }' file2 file1
我们本可以使用 match
而不是 index
,但是 match
将匹配 ERE 模式,如果 str
包含任何特殊的 ERE 模式,它将无法达到目的.