我有 2 个 TCL 表示,它们由同一工具的两个不同版本生成,我们将它们v1.tcl
称为v2.tcl
这些日志通常在所有意图和目的上都是逻辑上相同的,除了行的顺序之外。每一行v1.tcl
都会被发现某处v2.tcl
当我的项目的第 1 版和第 2 版相同时,恰好发生一次。
我希望能够确定是否有人做出了v2.tcl
需要反向移植的更改v1.tcl
(反之亦然)...换句话说,我只想看到不匹配的行。例如:
v1.tcl
:foo1 bar1 hello1 world1
v2.tcl
:hello1 bar1 foo2 world1 goodbye2
“diff”返回值:
file1:1 foo1 file2:3 foo2 file2:5 goodbye2
我是否应该编写自己的小脚本?是否有可以执行此操作的工具?
答案1
如果线条相同,而你只想知道如果一个文件或另一个文件中有多余的行,您可以使用 sort 和 diff (以及此处的进程替换):
$ diff -B <(sort v1.tcl) <(sort v2.tcl)
2c2,3
< foo1
---
> foo2
> goodbye2
使用 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
或者拆分成多行:
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
并且根据您的输入文件(特别是如果您有带有尾随反斜杠的行),我将使用这些选项进行读取和 grep:
read -r
不允许使用反斜杠转义任何字符grep -F
将 PATTERN 解释为固定字符串列表(而不是正则表达式),以换行符分隔,其中任何一个都可以匹配
另外,使用Pimp Juice IT's注释,如果输入文件中的行尾有反斜杠,grep 会给出“file:line Trailing backslash”错误。使用-F
grep 的选项清除尾随反斜杠错误会产生更小的仅 grep 解决方案:
grep -FvHn -f v2.tcl v1.tcl ;grep -FvHn -f v1.tcl v2.tcl
使用的 grep 选项:
-f
从 FILE 中获取模式,每行一个。-F
将 PATTERN 解释为固定字符串列表(而不是正则表达式),以换行符分隔,其中任何一个都可以匹配-v
反转匹配的方向,以选择不匹配的行。-H
打印每个匹配项的文件名-n
在输入文件中,为每行输出加上以 1 为基础的行号作为前缀。