我有一个包含几千个文件的目录,命名为:
filename.ext
filename (1).ext
filename (2).ext
otherfile.ext
otherfile (1).ext
etc.
Run Code Online (Sandbox Code Playgroud)
大多数带有括号的文件都是原始文件的副本,但在某些情况下它们不是.
如何保留原始文件,删除重复文件,但不丢失不同的文件?
我知道我可以rm *\).ext,但显然不能确保文件与原始文件匹配.
我正在使用OS X,所以我有一个md5类似于md5sumLinux的程序,尽管它将哈希放在行的末尾而不是开头.我以为我可以使用awk脚本获取输出md5 *.ext | awk 'some script',通过md5查找重复项,并删除它们,但命令行太长(bash: /sbin/md5: Argument list too long).
我不知道在剧本中写什么.我想用这个来存储数组中的东西:
awk '{a[$NF]++} a[$NF]>1{sub(/).*/,""); sub(/.*(/,""); system("rm " $0);}'
Run Code Online (Sandbox Code Playgroud)
但这似乎总是删除我原来的.
我究竟做错了什么?我该怎么做?
谢谢.
您的awk脚本会删除原始文件,因为在对文件进行排序时,.(句点)会在 (space). SO the first file that's seen is numbered, not the original, and subsequent checks (including the one against the original) compare files to the first numbered one.
Not only does rm *\).txt符合原始版本,它首先会丢失可能没有原件的文件.
我不会这样做.您可以浏览原始列表,然后删除与其匹配的编号文件,而不是检查每个编号文件并验证它是否与原始文件匹配.
代替:
$ for file in *[^\)].txt; do echo "-- Found: $file"; rm -v $(basename "$file" .txt)\ \(*\).txt; done
Run Code Online (Sandbox Code Playgroud)
您可以展开它以检查MD5.但是它的代码更多,所以我会在脚本中将它分成多行:
#!/bin/bash
shopt -s nullglob # Show nothing if a fileglob matches no files
for file in *[^\)].ext; do
md5=$(md5 -q "$file") # The -q option gives you only the message digest
echo "-- Found: $file ($md5)"
for duplicate in $(basename "$file" .ext)\ \(*\).ext; do
if [[ "$md5" = "$(md5 -q "$duplicate")" ]]; then
rm -v "$duplicate"
fi
done
done
Run Code Online (Sandbox Code Playgroud)
作为替代方案,您可以更简单地完成此操作,与计算MD5摘要相比,CPU开销更少.Unix和Linux有一个名为shell的工具cmp,就像diff没有输出一样.所以:
#!/bin/bash
shopt -s nullglob
for file in *[^\)].ext; do
for duplicate in $(basename "$file" .ext)\ \(*\).ext; do
if cmp "$file" "$duplicate"; then
rm -v "$file"
fi
done
done
Run Code Online (Sandbox Code Playgroud)