답변:
GNU 유틸리티 (또는 적어도 0으로 끝나는 행을 처리 할 수있는 세트)를 사용할 수 있다면 또 다른 대답 은 훌륭한 방법입니다.
find . -maxdepth 1 -print0 | sort -z | uniq -diz
참고 : 출력에는 0으로 끝나는 문자열이 있습니다. 추가 처리에 사용하는 도구는이를 처리 할 수 있어야합니다.
0으로 끝나는 줄을 처리하는 도구가 없거나 그러한 도구를 사용할 수없는 환경에서 코드가 작동하도록하려면 작은 스크립트가 필요합니다.
#!/bin/sh
for f in *; do
find . -maxdepth 1 -iname ./"$f" -exec echo \; | wc -l | while read count; do
[ $count -gt 1 ] && echo $f
done
done
이 광기는 무엇입니까? 미친 파일 이름을 안전하게 만드는 기술에 대한 설명은 이 답변 을 참조하십시오 .
-mindepth
합니까?
find
. 비 GNU 솔루션을 포함하도록 답변을 편집했습니다.
위의 많은 복잡한 답변이 있습니다. 이것은 모두보다 간단하고 빠릅니다.
find . -maxdepth 1 | sort -f | uniq -di
하위 디렉토리에서 중복 파일 이름을 찾으려면 전체 경로가 아닌 파일 이름 만 비교해야합니다.
find . -maxdepth 2 -printf "%f\n" | sort -f | uniq -di
편집 : Shawn J. Goff는 줄 바꿈 문자가있는 파일 이름이 있으면 이것이 실패 할 것이라고 지적했습니다. GNU 유틸리티를 사용하는 경우 다음 작업도 수행 할 수 있습니다.
find . -maxdepth 1 -print0 | sort -fz | uniq -diz
-print0
(발견을위한)와 -z
줄 바꿈 문자열을 종료하는 대신, 옵션 그 원인 NUL 종료 문자열에 일에 (종류 및 UNIQ에 대한). 파일 이름은 NUL을 포함 할 수 없으므로 모든 파일 이름에서 작동합니다.
대소 문자를 구분하지 않고 파일 이름 목록을 정렬하고 사본을 인쇄하십시오. sort
대소 문자를 구분하지 않는 정렬 옵션이 있습니다. GNU도 마찬가지 uniq
이지만 다른 구현은 아니며 uniq
, 처음 접하는 것을 제외한 모든 요소를 일련의 복제본으로 인쇄하기 만하면됩니다. GNU 도구를 사용하면 파일 이름에 줄 바꿈이 포함되어 있지 않다고 가정하면 모든 복제본 세트마다 하나씩 만 모든 요소를 인쇄하는 쉬운 방법이 있습니다.
for x in *; do printf "%s\n" "$x"; done |
sort -f |
uniq -id
파일 이름에 개행 문자가 없다고 가정하면 각 복제 세트의 모든 요소를 인쇄합니다.
for x in *; do printf "%s\n" "$x"; done |
sort -f |
awk '
tolower($0) == tolower(prev) {
print prev;
while (tolower($0) == tolower(prev)) {print; getline}
}
1 { prev = $0 }'
줄 바꿈이 포함 된 파일 이름을 수용해야하는 경우 Perl 또는 Python으로 이동하십시오. 아래 샘플 코드는 개행을 사용하여 자체 출력에서 이름을 구분하므로 출력을 조정하거나 동일한 언어로 추가 처리를 수행하는 것이 좋습니다.
perl -e '
foreach (glob("*")) {push @{$f{lc($_)}}, $_}
foreach (keys %f) {@names = @{$f{$_}}; if (@names > 1) {print "$_\n" foreach @names}}
'
다음은 순수한 zsh 솔루션입니다. 중복 요소를 배열 또는 glob 결과로 유지하는 기본 제공 방법이 없으므로 조금 장황합니다.
a=(*)(N); a=("${(@io)a}")
[[ $#a -le 1 ]] ||
for i in {2..$#a}; do
if [[ ${(L)a[$i]} == ${(L)a[$((i-1))]} ]]; then
[[ ${(L)a[$i-2]} == ${(L)a[$((i-1))]} ]] || print -r $a[$((i-1))]
print -r $a[$i]
fi
done
GNU없이 find
:
LANG=en_US ls | tr '[A-Z]' '[a-z]' | uniq -c | awk '$1 >= 2 {print $2}'
tr
이다 매우 문자 당 단일 바이트 이상을 사용하는 모든 문자 집합에 과시의 혼란에 가능성. UTF-8의 처음 256 자만 사용하면 안전 tr
합니다. 에서 위키 백과 TR (유닉스) .. 대부분의 버전의 tr
GNU 포함, tr
고전적인 유닉스 tr
, SINGLE BYTES에서 작동 및 유니 코드 호환되지 않는 ..
uniq
대소 문자를 구분하지 않는 플래그 i가 있습니다.
나는 마침내 이것을 이렇게 관리했다.
find . | tr '[:upper:]' '[:lower:]' | sort | uniq -d
나는 find
대신 ls
전체 경로 (많은 하위 디렉토리)가 필요했기 때문에 사용 했습니다 . 이 작업을 수행하는 방법을 찾지 못했습니다 ls
.
sort
와 uniq
각각 무시의 경우 플래그, F와 내가 있습니다.
그런 다음 파일 중 하나의 이름을 바꾸고 싶은 다른 사람들을 위해 :
find . -maxdepth 1 | sort -f | uniq -di | while read f; do echo mv "$f" "${f/.txt/_.txt}"; done