差异,同时忽略一行内的模式,但不是整行

Posted

技术标签:

【中文标题】差异,同时忽略一行内的模式,但不是整行【英文标题】:diff while ignoring patterns within a line, but not the entire line 【发布时间】:2013-04-05 18:42:12 【问题描述】:

我经常需要比较两个文件,而忽略这些文件中的某些更改。我不想忽略整行,只是其中的一部分。最常见的情况是行上的时间戳,但我也需要忽略其他几十种模式。

文件1:

[2012-01-02] Some random text foo
[2012-01-02] More output here

文件2:

[1999-01-01] Some random text bar
[1999-01-01] More output here

在此示例中,我想查看第 1 行的差异,而不是第 2 行的差异。

使用 diff 的 -I 选项将不起作用,因为它会忽略整行。理想输出:

--- file1       2013-04-05 13:39:46.000000000 -0500
+++ file2       2013-04-05 13:39:56.000000000 -0500
@@ -1,2 +1,2 @@
-[2012-01-02] Some random text foo
+[1999-01-01] Some random text bar
 [2012-01-02] More output here

我可以用 sed 预处理这些文件:

sed -e's/^\[....-..-..\]//' < file1 > file1.tmp
sed -e's/^\[....-..-..\]//' < file2 > file2.tmp
diff -u file1.tmp file2.tmp

但是我需要把这些临时文件放在某个地方,然后记得清理它们。此外,我的 diff 输出不再引用原始文件名,也不再发出原始行。

是否有广泛可用的 diff 变体或类似工具可以作为单个命令执行此操作?

【问题讨论】:

【参考方案1】:

您可以使用临时流来避免文件创建和清理,语法如下:

$ diff <(command with output) <(other command with output)

在你的情况下:

diff <(cat f1 | sed -e's/^\[....-..-..\]//') <(cat f2 | sed -e's/^\[....-..-..\]//')

希望这会有所帮助。

【讨论】:

没错。正如 Kernighan 在经典的软件工具中所说,尽可能对数据进行预处理,以使最终任务尽可能简单。【参考方案2】:

这不是您正在寻找的,因为我不确定如何保留日期,但这确实解决了您的几个问题:

diff -u --label=file1 <(sed 's/^\[....-..-..\]//' file1) --label=file2 <(sed 's/^\[....-..-..\]//' file2)

输出:

--- file1
+++ file2
@@ -1,2 +1,2 @@
- Some random text foo
+ Some random text bar
  More output here

【讨论】:

我认为日期可以包含在类似 '--label="file1 $(stat --printf "%y" file1)"' 中。听起来这是我能得到的最接近的结果,除非我去破解 diffutils 源代码。

以上是关于差异,同时忽略一行内的模式,但不是整行的主要内容,如果未能解决你的问题,请参考以下文章

如何在保持在另一列范围内的同时锻炼列中两个值之间的差异?

编辑 VBA UDF 以求和括号中的数字,同时忽略括号中的单词

尝试在 DataTable Bootstrap 中的每一行下显示按钮,但只能在特定列而不是整行下显示它们

hdfs文件格式

Sublime Text 3 快捷键整理

为啥 Mongoose 的 JavaScript 在同一行同时有返回和回调?