bash - 如何只检测我的 bash shell 脚本中的不同文件?

标签 bash shell unix hash md5

我正在尝试比较两个存储库中的文件列表,以尝试标记哪些文件已更改。问题是,我的代码说它们都是不同的。但是检查每个散列摘要表明许多摘要是相同的。

while IFS= read -r filename;
  do
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # inspecting the digest of each file individually         #
    # shows many files are identical and so are the digests   #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    md5 old/$filename; # a456cca87913a4788d980ba4c2f254be
    md5 new/$filename; # a456cca87913a4788d980ba4c2f254be
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # the below conditional is only supposed to echo "differs"    #
    # if the two digests are different                            #
    # but, instead, it echoes "differs" on every file comparison  #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    [[ $(md5 old/$filename) = $(md5 new/$filename) ]] || echo differs; # differs
  done < files-to-compare.txt

如何修复此错误并仅获取报告不同的文件?

编辑

此外,请注意使用 == 而不是 =

$(md5 old/$filename) == $(md5 new/$filename) ]] || echo differs; 

产生完全相同的错误输出。

编辑2

评论建议使用引号。那也行不通。

"$(md5 old/$filename)" == "$(md5 new/$filename)" ]] || echo differs; 

最佳答案

这里是你的脚本更正:

while IFS= read -r filename;
    do
        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        # inspecting the digest of each file individually         #
        # shows many files are identical and so are the digests   #
        # It also prints MD5 (full file path) = md5_signature!    #
        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        md5 "old/$filename"              # please use double quotes
        md5 "new/$filename" 
        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        # Using -q eliminates all output from md5 except the sig      #
        # Your script now works correctly                             #
        # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

        [[ $(md5 -q "old/$filename") == $(md5 -q "new/$filename") ]] || echo differs; # differs
    done < files.txt

问题:

  1. 你打错了 new/$fullfile 而不是 new/$filename
  2. 您应该在文件名扩展周围使用 "new/$filename"(即使用双引号)
  3. 使用md5 -q 比较md5 对不同文件的输出。否则 md5,默认情况下,以 MD5 (full_path/base_name) = 2504fcc0c0a57d14aa6b4193b5efaf94 的形式打印输入文件路径。由于这些路径在两个不同的目录中保证是不同的,不同的路径名将导致字符串比较失败。

上面的评论假定您在 BSD 上或可能在 macOS 上使用 md5

这是一个替代解决方案,它既可以在 Linux 上使用 md5sum 工作,也可以在 BSD 上使用 md5 工作。只需将文件的内容提供给任一程序的标准输入,并且只会打印 md5 签名:

$ md5 <new/file.pdf
2504fcc0c0a57d14aa6b4193b5efaf94

vs 如果使用文件名,则打印路径并打印使用的 MD5 哈希签名:

$ md5 new/file.pdf
MD5 (new/file.pdf) = 2504fcc0c0a57d14aa6b4193b5efaf94

Linux 或 GNU 核心实用程序上的 md5sum 也是如此。

关于bash - 如何只检测我的 bash shell 脚本中的不同文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53555729/

相关文章:

php - 从 php 执行 bash 脚本来执行 jar

linux - 搜索和替换(多行)

python - 无法使用bash脚本在virtualenv中运行python脚本

linux - BASH 使用 FIND 和 SED 在目录中的所有文件中查找和替换

shell脚本引用

linux - 如何使用 df 命令查找可用和已用内存总量

linux - 如何查找特定格式的数字并过滤掉特定范围的值?

bash - 如何拦截和删除 bash 中的命令行参数

sql - 如何从 Oracle SQL 语句中读取数据并将其传递给其他 shell 脚本?

linux - 在linux shell脚本中将多行添加到一行中