我有一个shell脚本,我需要检查两个文件是否包含相同的数据。我对很多文件都这样做,在我的脚本中,diff命令似乎是性能瓶颈。
歌词是这样的:
diff -q $dst $new > /dev/null
if ($status) then ...
是否有一种更快的方法来比较文件,也许是一个自定义算法而不是默认的diff?
我有一个shell脚本,我需要检查两个文件是否包含相同的数据。我对很多文件都这样做,在我的脚本中,diff命令似乎是性能瓶颈。
歌词是这样的:
diff -q $dst $new > /dev/null
if ($status) then ...
是否有一种更快的方法来比较文件,也许是一个自定义算法而不是默认的diff?
当前回答
如果您正在寻找更多可自定义的diff,那么可以使用git diff。
if (git diff --no-index --quiet -- old.txt new.txt) then
echo "files contents are identical"
else
echo "files differ"
fi
——安静 禁用程序的所有输出。意味着—退出代码。
—退出代码 使用类似diff(1)的代码退出程序。也就是说,如果有差异,它以1退出,0表示没有差异。
此外,还有各种算法和设置可供选择:
——diff-algorithm ={耐心| |最小直方图|迈尔斯} 选择一个差分算法。其变体如下: 基本的贪婪差分算法。目前,这是 违约。 花额外的时间来确保尽可能小的差异 生产。 在生成补丁时使用“patience diff”算法。 该算法将耐心算法扩展到“支持” 低发生率的公共元素”。
其他回答
还可以尝试使用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命令将输出文件的字节计数。参见“man cksum”。
因为我很糟糕,没有足够的声誉点,我不能把这个花絮作为评论。
但是,如果您打算使用cmp命令(并且不需要/不想太冗长),您可以只获取退出状态。根据cmp手册页:
如果FILE为'-'或缺失,则读取标准输入。退出状态为0 如果输入相同,1如果不同,2如果麻烦。
所以,你可以这样做:
STATUS="$(cmp --silent $FILE1 $FILE2; echo $?)" # "$?" gives exit status for each comparison
if [[ $STATUS -ne 0 ]]; then # if status isn't equal to 0, then execute code
DO A COMMAND ON $FILE1
else
DO SOMETHING ELSE
fi
编辑:感谢大家的评论!我在这里更新了测试语法。但是,如果您正在寻找与这个答案在可读性、风格和语法方面类似的东西,我建议您使用Vasili的答案。
你可以通过校验和算法进行比较,比如sha256
sha256sum oldFile > oldFile.sha256
echo "$(cat oldFile.sha256) newFile" | sha256sum --check
newFile: OK
如果文件是不同的,结果将是
newFile: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
对于没有不同的文件,任何方法都需要完全读取两个文件,即使读取是在过去。
除此之外别无选择。因此,在某个时间点上创建哈希或校验和需要读取整个文件。大文件需要时间。
文件元数据检索比读取大文件快得多。
那么,您是否可以使用任何文件元数据来确定这些文件是不同的? 文件大小?或者甚至文件命令只读取文件的一小部分的结果?
文件大小示例代码片段:
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'
如果文件大小相同,则只能读取完整的文件。
我相信cmp将在第一个字节差处停止:
cmp --silent $old $new || echo "files are different"