如何使 diff 命令忽略第二个文件(bash)的某些行?

如何使 diff 命令忽略第二个文件(bash)的某些行?

例如:

文件1.txt:

I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.

文件2.txt

I need to buy apples.
I need to run the laundry.
I need to wash the car.
I need to get the car detailed.

文件3.txt

I need to wash the car.

如果我这样做diff file1.txt file2.txt,则 diff 命令应忽略 file3.txt 中存在的语句(如果 file2.txt 中存在该语句)。所以,在这种情况下,应该没有区别。

使用忽略标志 ( diff -I "$line") 不会有帮助,因为它会在两个文件中找到模式。

我怎样才能做到这一点?

答案1

解决方法是删除相应的行,然后对其进行比较。也就是说, 和file1看起来file2都像:

I need to buy apples.
I need to run the laundry.

I need to get the car detailed.

grep您可以使用,perl和的组合来执行此操作sed

$ lines_to_ignore=$(grep -nFf file3 file2 | perl -pe 's|^(\d+):.*|$1s/.//g;|')
$ echo $lines_to_ignore 
3s/.//g;
$ diff <(sed "$lines_to_ignore" file1) <(sed "$lines_to_ignore" file2)        
$ echo $?
0
  • 我用来grep获取匹配的行(以及行号)file2
  • 然后我用来perl从输出中获取行号grep并从中生成 sed 命令(Ns/.//g删除第 N 行上的每个字符)。
  • sed然后,我使用进程替换将在文件上运行这些命令的结果提供给diff.

答案2

你可以在这里结合diffcombine

$ diff file1.txt <(combine file2.txt NOT file3.txt)
3d2
< I need to wash the dog.

更新以反映 OP 中的更改。

答案3

使用 grep 选项从文件中过滤掉行

$ diff f1 f2
3c3
< I need to wash the dog.
---
> I need to wash the car.
$ diff <( grep -v -f f3 -x f1) <( grep -v -f f3 -x f2)
3d2
< I need to wash the dog.

在哪里

  • <( )是创建临时文件的 bash 语法
  • 在 grep 中
    • -x匹配整个谎言
    • -f f3从文件 f3 中获取模式
    • -v显示不匹配的模式

答案4

diff可能不是正确的工具。听起来你需要使用comm,它将每一行分类为在一个文件中、在另一个文件中或在两个文件中共有。

但关键的限制是comm需要对两个输入文件进行排序

相关内容