Bash循环来比较文件

时间:2012-09-13 19:05:55

标签: linux bash loops if-statement while-loop

我显然遗漏了一些东西,并且知道问题是它正在创建一个空白输出,这就是它无法比较的原因。然而,如果有人能够对此有所了解,那就太棒了 - 我没有把它隔离开来。

最终,我正在尝试将存储在txt文件中的列表中的md5sum与存储在服务器上的列表进行比较。如果有错误,我需要它报告。这是输出:

root@vps [~/testinggrounds]# cat md5.txt | while read a b; do
>   md5sum "$b" | read c d
>   if [ "$a" != "$c" ] ; then
>     echo "md5 of file $b does not match"
>   fi
> done
md5 of file file1 does not match
md5 of file file2 does not match

root@vps [~/testinggrounds]# md5sum file*
2a53da1a6fbfc0bafdd96b0a2ea29515  file1
bcb35cddc47f3df844ff26e9e2167c96  file2

root@vps [~/testinggrounds]# cat md5.txt
2a53da1a6fbfc0bafdd96b0a2ea29515  file1
bcb35cddc47f3df844ff26e9e2167c96  file2

3 个答案:

答案 0 :(得分:7)

不是直接回答您的问题,而是md5sum(1)

-c, --check
read MD5 sums from the FILEs and check them

像:

$ ls
1.txt  2.txt  md5.txt
$ cat md5.txt
d3b07384d113edec49eaa6238ad5ff00  1.txt
c157a79031e1c40f85931829bc5fc552  2.txt
$ md5sum -c md5.txt
1.txt: OK
2.txt: OK

答案 1 :(得分:4)

您遇到的问题是您的内部读取是在子shell中执行的。在bash中,管道命令时会创建子shell。子shell退出后,变量$ c和$ d消失了。您可以使用进程替换来避免子shell:

while read -r -u3 sum filename; do
   read -r cursum _ < <(md5sum "$filename")
   if [[ $sum != $cursum ]]; then
      printf 'md5 of file %s does not match\n' "$filename"
   fi
done 3<md5.txt

重定向3<md5.txt导致文件作为文件描述符3打开。-u 3的{​​{1}}选项使其从该文件描述符中读取。内部read仍然从标准输入读取。

答案 2 :(得分:3)

我不会争辩。我只是尽量避免从内部循环中读取双重内容。

#! /bin/bash

cat md5.txt | while read sum file
do
    prev_sum=$(md5sum $file | awk '{print $1}')
    if [ "$sum" != "$prev_sum" ]
    then
        echo "md5 of file $file does not match"
    else
        echo "$file is fine"
    fi
done