gc5*_*gc5 0 bash cmp stderr io-redirection output
我正在尝试编写一个bash脚本,从文件夹中删除重复的文件,只保留一个副本.该脚本如下:
#!/bin/sh
for f1 in `find ./ -name "*.txt"`
do
if test -f $f1
then
for f2 in `find ./ -name "*.txt"`
do
if [ -f $f2 ] && [ "$f1" != "$f2" ]
then
# if cmp $f1 $f2 &> /dev/null # DOES NOT WORK
if cmp $f1 $f2
then
rm $f2
echo "$f2 purged"
fi
fi
done
fi
done
Run Code Online (Sandbox Code Playgroud)
我想重定向输出和stderr以/dev/null避免将它们打印到屏幕..但使用注释语句此脚本不能按预期工作并删除所有文件,但第一个..
如果需要,我会提供更多信息.
谢谢
几条评论:
一,:
for f1 in `find ./ -name "*.txt"`
do
if test -f $f1
then
Run Code Online (Sandbox Code Playgroud)
与(仅查找txt扩展名为普通文件)相同
for f1 in `find ./ -type f -name "*.txt"`
Run Code Online (Sandbox Code Playgroud)
更好的语法(仅限bash)是
for f1 in $(find ./ -type f -name "*.txt")
Run Code Online (Sandbox Code Playgroud)
最后整体是错误的,因为如果文件名包含空格,f1变量将不会获得完整的路径名.所以相反for做:
find ./ -type f -name "*.txt" -print | while read -r f1
Run Code Online (Sandbox Code Playgroud)
正如@Sir Athos指出的那样,文件名可以包含,\n所以最好使用
find . -type f -name "*.txt" -print0 | while IFS= read -r -d '' f1
Run Code Online (Sandbox Code Playgroud)
第二:
使用"$f1"而不是$f1- 再次,因为$f1可以包含空格.
第三:
进行N*N比较并不是很有效.你应该为每个txt文件做一个校验和(md5或更好的sha256).校验和相同时 - 文件是重复的.
如果您不信任校验和,则只需比较具有相同校验和的文件.具有不同校验和的文件确实不重复.;)
制作校验和很慢,所以你应该首先将ony文件与same size.不同大小的文件不重复...
你可以跳过空txt files- 它们都是重复的:).
所以最后的命令可以是:
find -not -empty -type f -name \*.txt -printf "%s\n" | sort -rn | uniq -d |\
xargs -I% -n1 find -type f -name \*.txt -size %c -print0 | xargs -0 md5sum |\
sort | uniq -w32 --all-repeated=separate
Run Code Online (Sandbox Code Playgroud)
评论说:
#find all non-empty file with the txt extension and print their size (in bytes)
find . -not -empty -type f -name \*.txt -printf "%s\n" |\
#sort the sizes numerically, and keep only duplicated sizes
sort -rn | uniq -d |\
#for each sizes (what are duplicated) find all files with the given size and print their name (path)
xargs -I% -n1 find . -type f -name \*.txt -size %c -print0 |\
#make an md5 checksum for them
xargs -0 md5sum |\
#sort the checksums and keep duplicated files separated with an empty line
sort | uniq -w32 --all-repeated=separate
Run Code Online (Sandbox Code Playgroud)
现在输出,您可以简单地编辑输出文件并决定要删除的内容以及要保留的文件.