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이렇게 하면 안 되는 몇 가지 이유는 다음과 같습니다.