如何diff的线的部分?(How to diff parts of lines?)

2019-07-18 05:29发布

我有我想diff的两个文件。 该行有时间戳,可能还有一些其他的东西,我想忽略匹配算法,但我还是希望这些项目输出,如果匹配算法找到的文本的其余部分的差异。 例如:

1c1
<    [junit4] 2013-01-11 04:43:57,392 INFO  com.example.MyClass:123 [main] [loadOverridePropFile] Config file application.properties not found: java.io.FileNotFoundException: /path/to/application.properties (No such file or directory)
---
>    [junit4] 2013-01-11 22:16:07,398 INFO  com.example.MyClass:123 [main] [loadOverridePropFile] Config file application.properties not found: java.io.FileNotFoundException: /path/to/application.properties (No such file or directory)

不应该被释放的,但是:

1c1
<    [junit4] 2013-01-11 04:43:57,392 INFO  com.example.MyClass:123 [main] [loadOverridePropFile] Config file application.properties not found: java.io.FileNotFoundException: /path/to/application.properties (No such file or directory)
---
>    [junit4] 2013-01-11 22:16:07,398 INFO  com.example.MyClass:456 [main] [loadOverridePropFile] Config file application.properties not found: java.io.FileNotFoundException: /path/to/application.properties (No such file or directory)

应该被发出(因为行号是不同的)。 需要注意的是时间戳仍然发出。

如何才能做到这一点?

Answer 1:

我希望此功能几次我面前,因为它再次弹出这里,我决定到google了一下周围,发现Perl的Algorithm::Diff您可以养活一个散列函数(他们称之为“密钥生成函数”)其中“应返回唯一标识一个给定的元素串”,该算法用来做比较(而不是说你给它的实际内容)。

基本上,所有你需要做的就是添加一个子,做一些正则表达式魔术,你的愿望,从您的字符串过滤掉不想要的东西,并为参数添加子参考,以调用的方式diff()见我的CHANGE 1CHANGE 2在下面的代码段的评论)。

如果您需要正常的(或统一) diff输出,检查精细diffnew.pl例如,该模块附带做在这个文件中进行必要的修改。 出于演示的目的,我会用简单的diff.pl ,它也附带,因为它是短暂的,我完全可以在这里发布它。

mydiff.pl

#!/usr/bin/perl

# based on diff.pl that ships with Algorithm::Diff
# demonstrates the use of a key generation function

# the original diff.pl is:
# Copyright 1998 M-J. Dominus. (mjd-perl-diff@plover.com)
# This program is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.

use Algorithm::Diff qw(diff);

die("Usage: $0 file1 file2") unless @ARGV == 2;

my ($file1, $file2) = @ARGV;

-f $file1 or die("$file1: not a regular file");
-f $file2 or die("$file2: not a regular file");
-T $file1 or die("$file1: binary file");
-T $file2 or die("$file2: binary file");

open (F1, $file1) or die("Couldn't open $file1: $!");
open (F2, $file2) or die("Couldn't open $file2: $!");
chomp(@f1 = <F1>);
close F1;
chomp(@f2 = <F2>);
close F2;

# CHANGE 1
# $diffs = diff(\@f1, \@f2);
$diffs = diff(\@f1, \@f2, \&keyfunc);

exit 0 unless @$diffs;

foreach $chunk (@$diffs)
{
        foreach $line (@$chunk)
        {
                my ($sign, $lineno, $text) = @$line;
                printf "%4d$sign %s\n", $lineno+1, $text;
        }
}
exit 1;

# CHANGE 2 {
sub keyfunc
{
        my $_ = shift;
        s/^(\d{2}:\d{2})\s+//;
        return $_;
}
# }

此时就把one.txt存盘

12:15 one two three
13:21 three four five

two.txt

10:01 one two three
14:38 seven six eight

例如运行

$ ./mydiff.pl one.txt two.txt
   2- 13:21 three four five
   2+ 13:21 seven six eight

示例运行2

这里是一个正常diff输出基础上, diffnew.pl

$ ./my_diffnew.pl one.txt two.txt
2c2
< 13:21 three four five
---
> 13:21 seven six eight

正如你所看到的,在任一文件的第一行被忽略,因为它们只在自己的时间戳不同,散列函数删除那些比较。

瞧,你刚刚推出自己的内容感知的diff



Answer 2:

假设你的文件“a.txt中”和“b.txt”。 您可以使用差异+切断这种方式得到它:

diff <(cut -d" " -f4-99 a.txt) <(cut -d" " -f4-99 b.txt)

每个切割忽略第一3个字段(与日期和这个东西),并且仅考虑了线(从柱4到99)的其余部分。 切应该工作使用:

cut -d" " -f4- a.txt

但它不为我工作,所以我加了-f4-99。 所以,我们采用切成两个输入忽略日期字段,然后我们运行差异,只要你想对它们进行比较。



文章来源: How to diff parts of lines?
标签: shell