要列出列表中重复的文件名?

要列出列表中重复的文件名?
bash-3.00$ cat f.txt
-rw-r--r--   1 mukesh   other        102 Nov  5 18:32 f1.txt
-rw-r--r--   1 mukesh   other         19 Nov  5 18:32 f2.txt
-rw-r--r--   1 mukesh   other        204 Nov  5 18:32 f3.txt //DUPLICATE
-rw-r--r--   1 mukesh   other        204 Nov  6 18:32 f3.txt  //DUPLICATE
-rw-r--r--   1 mukesh   other        204 Nov  6 18:32 f100.txt

假设我在名为 f.txt 的文件中列出了上述文件名。我想列出所有有重复的文件名(仅文件名),显示重复的文件名和重复的数量。

例如:在上面的列表中,f3.txt 有一个重复项,并且总共找到了 2 个 f3.txt 文件名。

答案1

正如您提到的awk,这是一个解决方案:

awk '{d[$9]++}END{for(f in d)if(d[f]>1)print d[f],f}' f.txt

如果您还有名称中包含空格字符的文件,则需要一些解决方法:

awk '{f=$9;for(i=10;i<=NF;i++)f=f" "$i;d[f]++}END{for(f in d)if(d[f]>1)print d[f],f}' f.txt

请注意,上述解决方法可能会失败,例如在处理符号链接时。毕竟,解析ls输出并不是一个好主意。如果可能的话,最好以其他方式生成 f.txt。 (例如findstat,您可以更好地控制列表格式。)

答案2

这是 pure 的解决方案bash,因为您的问题清楚地表明您有 bash 3 可用:

#!/bin/bash

if [[ -t 0 ]]; then
    printf '%s\n' 'No input!'
    exit 1
fi

while read -ra _file; do
    _file="${foo[*]:8}"

    for _file_name_already_known in "${_files[@]}"; do
        if [[ ${_file_name_already_known} == "${_file}" ]]; then
            for _file_name_already_printed in "${_already_printed[@]}"; do
                [[ ${_file_name_already_printed} == "${_file}" ]] && continue 3
            done
            printf '%s\n' "${_file}"
            _already_printed+=( "${_file}" )
        fi
    done

    _files+=( "${_file}" )
done

输出:

$ ./lsdups < f.txt
f3.txt

运行为./lsdups < file.

但请记住,ls输出并不是最好的选择。http://mywiki.wooledge.org/ParsingLs阐述了您不应该这样做的一些原因。

答案3

独特的实用程序删除或列出重复项。输入需要是已排序。由于只有文件名部分相关,因此请告诉这些实用程序忽略文件名左侧的内容。

sort -k 1.54 f.txt | uniq -s 54 -cd

相关内容