我正在编写一个脚本,我想从文件中获取每一行并检查另一个文件中的匹配项。 如果我找到一场比赛,我想说我找到了一场比赛,如果没有,请说我找不到比赛。
这2个文件包含md5哈希值。旧文件是原始文件,新文件用于检查自原始文件以来是否有任何更改。
原始文件:chksum 新文件:chksum1
#!/bin/bash
while read e; do
while read f; do
if [[ $e = $f ]]
then
echo $e "is the same"
else
if [[ $e != $f]]
then
echo $e "has been changed"
fi
fi
done < chksum1
done < chksum
我的问题是,对于已经更改的文件,每次完成循环中的检查时我都会得到一个回声,而我只希望它显示一次文件,并说它没有找到。
希望这很清楚。
答案 0 :(得分:0)
你可以使用相同的脚本但提醒一下。
#!/bin/bash
while read e; do
rem=0
while read f; do
if [[ $e = $f ]]
then
rem=1
fi
done < chksum1
if [[ rem = 1 ]]
then
echo $e "is the same"
else
echo $e "has been changed"
fi
done < chksum
这应该可以正常工作
答案 1 :(得分:0)
你真的很亲密。这将有效:
while read e; do
while read f; do
found=0
if [[ $e = $f ]]
then
# echo $e "is the same"
found=1
break
fi
done < chksum1
if [ $found -ne 0 ]
then
echo "$e is the the same"
else
echo "$e has been changed"
fi
done < chksum
答案 2 :(得分:0)
一点点简化版本,避免多次读取同一文件(bash 4.0及以上版本)。我假设文件包含唯一的文件名,文件格式是md5sum命令的输出。
#!/bin/bash
declare -A hash
while read md5 file; do hash[$file]=$md5; done <chksum
while read md5 file; do
[ -z "${hash[$file]}" ] && echo "$file new file" && continue
[ ${hash[$file]} == $md5 ] && echo "$file is same" && continue
echo "$file has been changed"
done <chksum1
此脚本将第一个文件读取到一个名为hash
的关联数组。索引是文件的名称,值是MD5校验和。第二个循环读取第二个校验和文件;文件名不在hash
打印file new file
;如果它在hash
并且值等于那么它是同一个文件;如果它不等于它写file has been changed
。
输入文件:
$ cat chksum
eed0fc0313f790cec0695914f1847bca ./a.txt
9ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
a91a408e113adce865cba3c580add827 ./c.txt
$ cat chksum1
eed0fc0313f790cec0695914f1847bca ./a.txt
8ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
a91a408e113adce865cba3c580add827 ./d.txt
输出:
./a.txt is same
./b.txt has been changed
./d.txt new file
扩展版
还检测已删除的文件。
#!/bin/bash
declare -A hash
while read md5 file; do hash[$file]=$md5; done <chksum
while read md5 file; do
[ -z "${hash[$file]}" ] && echo "$file new file" && continue
if [ ${hash[$file]} == $md5 ]; then echo "$file is same"
else echo "$file has been changed"
fi
unset hash[$file]
done <chksum1
for file in ${!hash[*]};{ echo "$file deleted file";}
输出:
./a.txt is same
./b.txt has been changed
./d.txt new file
./c.txt deleted file
答案 3 :(得分:0)
我想建议一个替代解决方案:如何逐行阅读,但使用sort
和uniq -c
查看是否存在差异。没有必要使用简单的管道来完成工作。
在这种情况下,您需要文件chksum1
中已更改的所有行,所以
sort chksum chksum1 chksum1 | uniq -c | egrep '^\s+2\s' | sed 's%\s\+2\s%%'
与基于循环的示例相比,这也只读取chksum1
2次,每个行chksum
读取一次。
重用其他答案之一的输入文件:
samveen@precise:~/so$ cat chksum
eed0fc0313f790cec0695914f1847bca ./a.txt
9ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
a91a408e113adce865cba3c580add827 ./c.txt
samveen@precise:~/so$ cat chksum1
eed0fc0313f790cec0695914f1847bca ./a.txt
8ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
a91a408e113adce865cba3c580add827 ./d.txt
samveen@precise:~/so$ sort chksum chksum1 chksum1 |uniq -c | egrep '^\s+2\s' |sed 's%\s\+2\s%%'
8ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
a91a408e113adce865cba3c580add827 ./d.txt
另一种可能的解决方案是(在问题的评论中建议)将diff
与sort
结合使用:
diff <(sort chksum) <(sort chksum1) |grep '^>'
输出:
samveen@precise:~/so$ diff <(sort chksum) <(sort chksum1) |grep '^>'
> 8ee9e1fffbb3c16357bf80c6f7a27574 ./b.txt
> a91a408e113adce865cba3c580add827 ./d.txt
答案 4 :(得分:0)
简单的解决方案:
diff -q chksum1 chksum
答案 5 :(得分:0)
使用命令grep怎么样?您从chksum读取的每一行都将作为chksum1中的搜索模式。如果grep找到匹配项,则包含grep返回值的"$?"
将等于0
,否则它将等于1
while read e; do
grep $e checksum1
if[ $? == "0" ];then
echo $e "is the same"
else
echo $e "has been changed"
fi
done < chksum