如何检查file1是否为file2的前缀?


13

我有两个文件,大小分别为124665和124858(以字节为单位),并想检查file1是否为file2的前缀。

Answers:


11

假设您file1在变量中具有的大小,FILE1_SZ并且您的head实现支持(非标准)-c选项:

if head -c "$FILE1_SZ" file2 | cmp -s - file1; then
    echo "file1 is a prefix of file2"
else
    echo "file1 is not a prefix of file2"
fi

@StéphaneChazelas您能解释一下为什么cmp会比diff这里更好吗?
2014年

7
因为进行cmp了简单的字节到字节比较,并在发现差异时立即返回,而difftext实用程序将使用复杂的算法来向您显示两个文件中您不需要关心的所有差异。
斯特凡Chazelas

12

如果您的系统具有cmp来自GNU 的命令diffutils,则一种选择是

cmp -n 124665 file1 file2

比较两个文件的前124665个字节,并报告它们是否不同-或更一般地说,

cmp -n "$(wc -c < file1)" file1 file2

@StephaneChazelas我第二次在这里猜测自己,但建议$(stat -c %s file1)以字节为单位的大小会更好吗?是否wc真的打开并处理了整个文件以获得字节数?
steeldriver 2014年

2
不,大多数wc实现都会优化这种情况并执行一个fstat()(或/和一个lseek(SEEK_END)),因此将尽可能高效。另一方面,这stat -c是GNU特定的。
斯特凡Chazelas

1
尽管如果您需要特定于GNU的代码cmp,则可以合理地假设特定于GNU的代码stat
2014年

3

GNU cmp可以通过一种更简单的方式解决问题:

cmp file1 file2

有四个可能的输出(除非出现某种错误)。

  • 无输出:文件相同。

  • cmp: EOF on file1:file1是file2的前缀。

  • cmp: EOF on file2:file2是file1的前缀。

  • file1 file2 differ: byte NNN, line MMM:两者都不是另一个的前缀。

不幸的是,这在脚本中使用有点尴尬,因为这些情况在退出代码中似乎没有区别。此外,EOF on file1消息转到stderr,而file1 file2 differ消息转到stdout。

我认为其他版本的软件cmp也可以执行类似的操作,但我尚未检查。


1
cmp它不是仅用于GNU的命令,也不是起源于此的命令,它早在70年代初就已出现在Unix的第一个版本中。该-n选项是特定于GNU的。
斯特凡Chazelas

你可以做cmp file1 file2 2>&1 | grep EOF on file1
David Z

@StéphaneChazelas:是的。我并不是说这cmp是GNU所独有的,只是GNU cmp是我尝试过的唯一版本。我加了一句话来澄清。
Nate Eldredge 2014年

@DavidZ:是的,可以,但是它的健壮性要差一些。想象一下,您尝试使用用户提供的两个文件来执行此操作,其中一个名为file1,另一个名为file12。(或者更糟糕的是,如果第二个文件被命名EOF on file1为该怎么办?)与使用cmpC语言编写明显的5行程序相比,健壮地解决此问题可能要麻烦得多……
Nate Eldredge 2014年

但是,在某些情况下,C程序不实用。而且使其相当强大并不难,因为的输出cmp受到了如此严格的限制。使用-x选项on grep匹配整行将处理除最特殊情况以外的所有情况(例如,文件名中的换行符)。
David Z
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.