文件头不同


11

我有两个文件。我怀疑一个文件是另一个文件的子集。有没有一种方法可以区分文件(以简洁的方式)以确定第二个文件在第一个文件中的合适位置?



您是说一个文件的行是另一个文件的子序列,还是实际上是连续的子字符串?
卡兹(Kaz)

连续的子字符串@Kaz。
理查德

Answers:


14

diff -e bigger smaller 可以解决问题,但是需要一些解释,因为输出是“有效的ed脚本”。

我制作了两个文件“ bigger”和“ smaller”,其中“ smaller”的内容与“ bigger”的第5行到第9行相同,这是通过`diff -e更大更小”得到的:

% diff -e bigger smaller
10,15d
1,4d

这意味着“删除第10至15行'更大',然后删除第1至4行以获得'更小'”。这意味着“较小”是“较大”的第5至9行。

反转文件名使我变得更加复杂。如果“较小”确实构成“较大”的子集,则输出中仅显示“ d”(用于删除)命令。


5

您可以使用Meld直观地执行此操作。不幸的是,它是一个GUI工具,但是如果您只想执行一次,并且文件相对较小,那就可以了:

下图是的输出meld a b

在此处输入图片说明


1
Meld很不错,但是在100MB以上的文件中播放效果并不理想。
理查德

@Richard不,不是,我还是更喜欢命令行工具,我只是以为我会提到它。
terdon

看起来很像vimdiff,可以在终端中使用。
Patrick

2

如果文件足够小,则可以将它们都放到Perl中,并让其正则表达式引擎来解决:

perl -0777e '
        open "$FILE1","<","file_1";
        open "$FILE2","<","file_2";
        $file_1 = <$FILE1>;
        $file_2 = <$FILE2>;
        print "file_2 is", $file_1 =~ /\Q$file_2\E/ ? "" : "not";
        print " a subset of file_1\n";
'

-0777指示的Perl开关到其输入记录分隔符设置$/到未定义的值,以便完全啜食文件。


1
怎么777办?我认为您传递的是NULL,$/但为什么呢?同样,由于这些都是有点深奥的开关,因此对于非perl人士来说是一个很好的解释。
terdon

1
@terdon我确实是在做整个文件。添加说明。
约瑟夫R.13年

但是为什么有必要呢?$a=<$fh>还是应该lur一口吧?
terdon

1
@terdon我不知道,不。默认情况下$/设置为,\n以便$a=<$fh>只读取$fh已打开到文件的一行。当然,除非perl我的命令行行为具有我不知道的不同默认值?
Joseph R.

啊,是的,我不好,我几乎从不吸收文件或使用while $foo=<FILE>惯用语,所以我不确定是否运行了(错误的)测试,该测试似乎可行。没关系 :)。
terdon

1

如果这些文件是文本文件,并且smaller在内bigger以一行开头开始,则使用以下命令实现起来并不难awk

awk -v i=0 'NR==FNR{l[n++]=$0;next}
    {if ($0 == l[i]) {if (++i == n) {print FNR-n+1;exit}} else i=0}
    ' smaller bigger

1

您的问题是“不同的文件头”。如果您真的是说一个文件是另一个文件的头,那么一个简单的cmp告诉您:

cmp big_file small_file
cmp: EOF on small_file

这告诉您,在读取时到达文件末尾之前,未检测到两个文件之间的差异small_file

但是,如果您表示小文件的整个文本可以出现在内的任何位置big_file,则假定您可以将两个文件都放入内存中,则可以使用

perl -le '
   use autodie;
   undef $/;
   open SMALL, "<", "small_file";
   open BIG, "<", "big_file";
   $small = <SMALL>;
   $big = <BIG>;
   $pos = index $big, $small;
   print $pos if $pos >= 0;
'

这将big_file在的内容所在的位置打印偏移量small_file(例如,如果small_file开头匹配则为0 big_file)。如果small_file内部不匹配big_file,则不会打印任何内容。如果有错误,退出状态将为非零。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.