将第一个文件中的每一行与第二个文件中的所有行进行比较?

IDL*_*yer 2 script bash diff vim command-line

我有得到由2个不同版本的同一工具生成的项目2所TCL表示,让我们给他们打电话v1.tclv2.tcl

除了行的顺序之外,这些日志对于所有意图和目的在逻辑上通常是相同的。当我的项目的版本 1 和 2 相同时,每行都v1.tcl将在某处恰好出现一次v2.tcl

我希望能够确定是否有人做出了v2.tcl需要向后移植的更改v1.tcl(或反之亦然)……换句话说,我只想看到不匹配的行。例如:

  1. v1.tcl

    foo1
    bar1
    hello1
    world1
    
    Run Code Online (Sandbox Code Playgroud)
  2. v2.tcl

    hello1
    bar1
    foo2
    world1
    goodbye2
    
    Run Code Online (Sandbox Code Playgroud)
  3. “差异”返回值:

    file1:1 foo1
    file2:3 foo2
    file2:5 goodbye2
    
    Run Code Online (Sandbox Code Playgroud)

我应该写我自己的小脚本吗?有没有工具可以做到这一点?

Xen*_*050 5

如果这些行是相同的,并且您只想知道一个文件或另一个文件中是否有额外的行,则可以使用 sort & diff(和此处的 Process Substitution):

$ diff -B <(sort v1.tcl) <(sort v2.tcl)
2c2,3
< foo1
---
> foo2
> goodbye2
Run Code Online (Sandbox Code Playgroud)

使用 diff-B忽略空行。然后,您可以使用grep -n [pattern] file来查找模式所在的行(可能使用grep, cut, sed, 中的一个或组合awk),如果这很重要的话。

这是一个更完整的答案,显示包含匹配项的文件和行号。不使用 sed 或 awk,只使用 bash、cut、grep ......这一切(基本上)在一行中:

diff -B <(sort v1.tcl) <(sort v2.tcl) | while read -r line; do if \
echo "$line" | grep -q "^<"; then grep -F -n -H \
"$(echo "$line"|cut -c3-)" v1.tcl ; elif echo "$line" | grep -q \
"^>"; then grep -F -n -H "$(echo "$line"|cut -c3-)" v2.tcl ; fi done
Run Code Online (Sandbox Code Playgroud)

或者拆分成多行:

diff -B <(sort v1.tcl) <(sort v2.tcl) | while read -r line
do
  if echo "$line" | grep -q "^<"
    then grep -F -n -H "$(echo "$line"|cut -c3-)" v1.tcl
  elif echo "$line" | grep -q "^>"
    then grep -F -n -H  "$(echo "$line"|cut -c3-)" v2.tcl
  fi
done
Run Code Online (Sandbox Code Playgroud)

并且根据您的输入文件(特别是如果您有带有尾随反斜杠的行),我将这些选项用于 read & grep:

  • read -r 不允许反斜杠转义任何字符
  • grep -F 将 PATTERN 解释为固定字符串列表(而不是正则表达式),以换行符分隔,其中任何一个都将被匹配

此外,使用Pimp Juice IT 的评论,如果输入文件中的行尾随反斜杠 grep 会给出“file:line 尾随反斜杠”错误。使用-Fgrep 选项清除尾随反斜杠错误会产生更小的 grep-only 解决方案:

grep -FvHn -f v2.tcl v1.tcl ;grep -FvHn -f v1.tcl v2.tcl
Run Code Online (Sandbox Code Playgroud)

grep 使用的选项:

  • -f 从 FILE 获取模式,每行一个。
  • -F 将 PATTERN 解释为固定字符串列表(而不是正则表达式),以换行符分隔,其中任何一个都将被匹配
  • -v 反转匹配感,选择不匹配的行。
  • -H 打印每个匹配项的文件名
  • -n 在其输入文件中使用从 1 开始的行号为每一行输出添加前缀。