我尝试从包含 20k 个文件的目录中删除重复文件。我发现重复文件虽然文件名不同,但文件大小相同。所以我想先按文件大小对它们进行排序,然后将它们逐个输入到 for-to 循环中,以比较当前文件的大小和前一个文件的大小。
问题是文件名包含空格,这对我来说处理起来太困难了,因为我最终将文件名分成单独的参数。
我尝试了以下两种方法:
1.
last=0
for filename in *
do
current=`du -b "${filename}" | cut -f1`
if [ $current -eq $last ]
then
rm "$filename"
fi
last=$current
done
如果重复项紧接着出现,这种方法是可行的。由于排序顺序不默认其大小,因此会保留大量重复项。
2.
last=0
for filename in `ls -AS`
do
current=`du -b "${filename}" | cut -f1`
if [ $current -eq $last ]
then
rm "$filename"
fi
last=$current
done
这是行不通的,因为文件名没有正确传递给“文件名”,而是被切成碎片,因为每个空格都被视为分隔符。
我怎样才能结合这两种方法?
答案1
虽然我同意使用像md5sum
和shasum
这样的实用程序远的在检测重复项方面比文件大小更有效(如评论中所述),这个问题的根源似乎更多地是关于当名称中包含空格时如何对文件进行排序。我相信您可以使用它来做ls -S1
您想要的事情,因为这将使输出的ls
每个逻辑行都有一个文件名(按大小排序)。如果您将 IFS 变量更改为在换行符处中断,您应该会得到您想要的结果。下面是一些示例代码说明:
ORIG_IFS="${IFS}"
IFS=$'\n'
for CURR_FILE in $(ls -S1)
do
echo "Next file: ${CURR_FILE}"
done
IFS="${ORIG_IFS}"
如果您选择使用md5sum
或 ,shasum
您将看到命令输出在每个输出行的开头打印哈希值,后跟文件名。然后,您可以sort
输出(将重复的哈希值行放在一起),使用 cut 命令从行开头剥离固定长度的哈希值,并以类似于您尝试处理文件大小的方式进行处理。