判断两个文件在Unix / Linux中是否相同的最快方法?

时间:2012-10-15 17:06:13

标签: linux file unix diff

我有一个shell脚本,我需要检查两个文件是否相同。我这样做是为了很多文件,在我的脚本中,diff命令似乎是性能瓶颈。

这是一行:

diff -q $dst $new > /dev/null

if ($status) then ...

有没有更快的方法来比较文件,可能是自定义算法而不是默认的diff

9 个答案:

答案 0 :(得分:319)

我相信cmp将停在第一个字节差异处:

cmp --silent $old $new || echo "files are different"

答案 1 :(得分:41)

我喜欢@Alex Howansky为此使用'cmp --silent'。但我需要积极和消极的回应,所以我使用:

cmp --silent file1 file2 && echo '### SUCCESS: Files Are Identical! ###' || echo '### WARNING: Files Are Different! ###'

然后我可以在终端中运行它或使用ssh来检查文件与常量文件。

答案 2 :(得分:16)

为什么不获取两个文件内容的哈希值?

尝试使用此脚本,将其命名为script.sh,然后按如下方式运行:script.sh file1.txt file2.txt

#!/bin/bash

file1=`md5 $1`
file2=`md5 $2`

if [ "$file1" = "$file2" ]
then
    echo "Files have the same content"
else
    echo "Files have NOT the same content"
fi

答案 3 :(得分:4)

对于没有差异的文件,任何方法都需要完全读取这两个文件,即使读取过去也是如此。

别无选择。因此,在某个时间点创建哈希值或校验和需要读取整个文件。大文件需要时间。

文件元数据检索比读取大文件要快得多。

那么,是否有可用于确定文件不同的文件元数据? 文件大小 ?甚至文件命令的结果只读取文件的一小部分?

文件大小示例代码片段:

  ls -l $1 $2 | 
  awk 'NR==1{a=$5} NR==2{b=$5} 
       END{val=(a==b)?0 :1; exit( val) }'

[ $? -eq 0 ] && echo 'same' || echo 'different'  

如果文件大小相同,那么您将无法使用完整的文件读取。

答案 4 :(得分:3)

要快速安全地比较任何两个文件:

if cmp --silent -- "$FILE1" "$FILE2"; then
  echo "files contents are identical"
else
  echo "files differ"
fi

答案 5 :(得分:2)

还要尝试使用cksum命令:

chk1=`cksum <file1> | awk -F" " '{print $1}'`
chk2=`cksum <file2> | awk -F" " '{print $1}'`

if [ $chk1 -eq $chk2 ]
then
  echo "File is identical"
else
  echo "File is not identical"
fi

cksum命令将输出文件的字节数。请参阅&#39; man cksum&#39;。

答案 6 :(得分:1)

因为我很烂,并且没有足够的声望点,所以不能在评论中添加这个花絮。

但是,如果您要使用cmp命令(并且不需要/不想太冗长),则只需获取退出状态即可。根据{{​​1}}手册页:

  

如果FILE是'-'或丢失,请阅读标准输入。退出状态为0   如果输入相同,则为1,如果不同,则为2。

因此,您可以执行以下操作:

cmp

答案 7 :(得分:1)

您可以通过诸如sha256之类的校验和算法进行比较

sha256sum oldFile > oldFile.sha256

echo "$(cat oldFile.sha256) newFile" | sha256sum --check

newFile: OK

如果文件是不同的,结果将是

newFile: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

答案 8 :(得分:0)

使用Raspberry Pi 3B +做一些测试(我正在使用覆盖文件系统,并且需要定期同步),我对diff -q和cmp -s进行了自己的比较;请注意,这是来自/ dev / shm内部的日志,因此磁盘访问速度不是问题:

[root@mypi shm]# dd if=/dev/urandom of=test.file bs=1M count=100 ; time diff -q test.file test.copy && echo diff true || echo diff false ; time cmp -s test.file test.copy && echo cmp true || echo cmp false ; cp -a test.file test.copy ; time diff -q test.file test.copy && echo diff true || echo diff false; time cmp -s test.file test.copy && echo cmp true || echo cmp false
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 6.2564 s, 16.8 MB/s
Files test.file and test.copy differ

real    0m0.008s
user    0m0.008s
sys     0m0.000s
diff false

real    0m0.009s
user    0m0.007s
sys     0m0.001s
cmp false
cp: overwrite âtest.copyâ? y

real    0m0.966s
user    0m0.447s
sys     0m0.518s
diff true

real    0m0.785s
user    0m0.211s
sys     0m0.573s
cmp true
[root@mypi shm]# pico /root/rwbscripts/utils/squish.sh

我跑了几次。 cmp -s在我使用的测试箱上始终具有略短的时间。因此,如果您想使用cmp -s在两个文件之间进行操作。...

identical (){
  echo "$1" and "$2" are the same.
  echo This is a function, you can put whatever you want in here.
}
different () {
  echo "$1" and "$2" are different.
  echo This is a function, you can put whatever you want in here, too.
}
cmp -s "$FILEA" "$FILEB" && identical "$FILEA" "$FILEB" || different "$FILEA" "$FILEB"