목록에 중복된 파일 이름을 나열하고 싶으십니까?

목록에 중복된 파일 이름을 나열하고 싶으십니까?
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를 생성하는 것이 좋습니다. (예를 들어 find목록 stat형식을 더 세부적으로 제어할 수 있습니다.)

답변2

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

관련 정보