比较两个文件,忽略第一列并打印行号

比较两个文件,忽略第一列并打印行号

如何打印差异行号,忽略制表符分隔文件的第一列?

示例 - 通过忽略第一列和打印行号来比较文件 1 和文件 2。对于文件 2 中存在的差异记录。

在文件1中:

user1   fistname    Lastnamename
user2   Johnny            Depp
user3   Tom               Cruise
user4   Leonardo          DiCaprio
user5   Sylvester         Stallone

在文件2中:

user10   fistname    Lastnamename
user2   Johnny            Depp
user30  Tom'               Cruise
user4   Nicolas           Cage
user50  Sylvester         Stallone

预期结果:- file2 中的差异在于行号 3,4

注意要比较的文件大小以 GB 为单位,文件以制表符分隔

答案1

您可以使用 diff 命令和 cut 来查找两个文件中的差异。

diff <(cut -f2 -d$'\t' file1) <(cut -f2 -d$'\t' file2)

输出将是

3,4c3,4
< Tom
< Leonardo
---
> Tom'
> Nicolas

如果您担心更多的重复记录,那么您可以使用上面的命令来sort -u删除重复记录,然后再从其他文件中查找差异。命令将是

diff <(cut -f2 -d$'\t' file1|sort -u) <(cut -f2 -d$'\t' file2|sort -u)

答案2

尝试使用此代码,不知道这是否有效,因为我没有足够的数据:

diff --unchanged-line-format="" --old-line-format="" --new-line-format=":%dn: %L" file1 file2 | sed 1d | cut -d':' -f2 |tr '\n' ','|sed 's/,$//g'

答案3

这可以回答你的问题:

awk 'NR==FNR{++a[$2,$3];next} {line++;if(!(a[$2,$3])){print line}}' record1 record2

解释:

FNR==NR

当您有两个(或更多)输入文件时awk,FNR 将在下一个文件的第一行重置回 1,而 NR 将从中断处继续递增。通过检查,FNR==NR我们实际上是在检查当前是否正在解析第一个文件。

++a[$2,$3]

如果我们正在解析第一个文件(见上文),则创建一个关联数组,其中第一个字段 $2 和第二个字段 $3 作为键,然后将值增加 1。这本质上让我们创建一个“已看到”列表。

next

该命令告诉 awk 不要处理任何进一步的命令并读入下一条记录并重新开始。我们这样做是因为 file1 仅用于设置关联数组

!(a[$2,$3])

该行仅在 FNR==NR 为 false 时执行,即我们不解析 file1,因此必须解析 file2。然后,我们使用 file2 的第一个字段 $1 和第二个字段 $2 作为索引到之前创建的“已查看”列表的键。如果返回的值为 0,则意味着我们在 file1 中没有看到它,因此我们应该打印这一行。相反,如果该值非零,那么我们确实在 file1 中看到了它,因此我们不应该打印它的值。请注意 !(a[$2,$3]) 相当于 !(a[$2,$3]){print} 因为未给出时的默认操作是打印整行。

答案4

$ echo -n 'difference in file2 is for line number ';diff --unchanged-line-format="" --old-line-format="" --new-line-format="%dn " <(tail +2 file1|unexpand -a|cut -f2-) <(tail +2 file2|unexpand -a|cut -f2-)|grep -o "[0-9]*" | while read i;do echo $((i+1));done|paste -sd,
difference in file2 is for line number 3,4

相关内容