对 Bash 文件中 for 循环中使用的文件进行排序

对 Bash 文件中 for 循环中使用的文件进行排序

我尝试从包含 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

虽然我同意使用像md5sumshasum这样的实用程序远的在检测重复项方面比文件大小更有效(如评论中所述),这个问题的根源似乎更多地是关于当名称中包含空格时如何对文件进行排序。我相信您可以使用它来做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 命令从行开头剥离固定长度的哈希值,并以类似于您尝试处理文件大小的方式进行处理。

相关内容