如何打印差异行号,忽略制表符分隔文件的第一列?
示例 - 通过忽略第一列和打印行号来比较文件 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