Mac OSX를 실행 중이며 명령 줄을 사용하여 이름이 같은 파일 수를 찾습니다.
다음 명령을 사용하려고했습니다.
find ~ -type f -name "*" -print | basename | sort | uniq -d > duplicate_files
작동하지 않습니다! 내가 다음을 할 때 :
find ~ -type f -name "*" -print > duplicate_files
그런 다음 duplicate_files에는 모든 파일의 경로가 포함됩니다. 따라서 문제는 basename
표준 입력을 허용하지 않습니다. 그런 다음 다음을 시도했습니다.
basename $(find ~ -type f -name "*" -print) > duplicate_files
그러나 다시는 작동하지 않는 것 같습니다. 인터넷 검색은 큰 기쁨을 얻지 못하는 것 같습니다. 어떤 생각이라도 가장 환영합니다.
답변
basename
명령 행 인수에서 작동하며 표준 입력에서 읽지 않습니다.
basename
유틸리티 를 호출 할 필요가 없으며 더 나은 방법은 아닙니다. 마지막 전에 부분을 제거하고 /
각 항목에 대해 외부 명령을 호출하는 것이 느릴 것입니다. 텍스트 처리를 사용할 수 있습니다 대신 유틸리티.
find ~ -type f | sed 's!.*/!!' | sort | uniq -d
파일 위치를 추적하는 것이 더 유용 할 수 있습니다. 이름별로 정렬하면 중복을 쉽게 찾을 수 있지만 sort
마지막 필드를 사용할 수있는 옵션이 없습니다. 당신이 할 수있는 일은 마지막 /
으로 구분 된 필드를 처음으로 복사 한 다음 정렬 한 다음 약간의 임시 처리를 사용하여 복제본을 추출하고 제시하는 것입니다.
find ~ -type f |
sed 's!.*/\(.*\)!\1/&!' | # copy the last field to the beginning
sort -t/ -k1,1 |
cut -d/ -f2- | # remove the extra first field (could be combined with awk below)
awk -F / '{
if ($NF == name) {
if (previous != "") {print previous; previous = ""}
print
} else {
previous = $0
name = $NF
}
'
(파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.)
답변
내장 find
기능 을 사용 하여 파일 이름 만 출력 하지 않는 이유는 무엇입니까?
find ~ -type f -printf '%f\n' | sort | uniq -c
(GNU 가정 find
) 또는 적어도 다음과 같은 것 :
find ~ -exec basename {} \; | sort | uniq -c
basename
파이프를 통해 읽거나 여러 파일을 한 번에 처리 할 수 없습니다.
추신. -name '*'
모든 파일을 나열하려는 경우 지정할 필요가 없습니다 . 이것이 기본 옵션입니다.
답변
이것은 OSX에서 나를 위해 작동하는 것 같습니다 :
find ~ -type f -exec basename -a {} + | sort | uniq -d
답변
대안 (파일 이름에 줄 바꿈이 없다고 가정) :
find ~ -type f | awk -F/ '{print $NF}' | sort | uniq -d
답변
xargs
with basename
를 사용 하여 다음과 같이 원하는 출력을 얻을 수 있습니다 .
find ~ -type f -name "*" -print | xargs -l basename | sort | uniq -d > duplicate_files
답변
최신 버전의 bash
연관 배열을 처리하면 다음과 같이 개행 문자가 포함 된 경로 이름을 추가로 처리 할 수 있습니다.
#!/bin/bash
topdir=$HOME
shopt -s globstar # enable the ** glob
declare -A count
# count the number of times each filename (base name) occurs
for pathname in "$topdir"/**; do
# skip names that are not regular files (or not symbolic links to such files)
[ ! -f "$pathname" ] && continue
# get the base name
filename=${pathname##*/}
# add one to this base name's count
count[$filename]=$(( ${count[$filename]} + 1 ))
done
# go through the collected names and print any name that
# has a count greater than one
for filename in "${!count[@]}"; do
if [ "${count[$filename]}" -gt 1 ]; then
printf 'Duplicate filename: %s\n' "$filename"
fi
done
이것은 외부 유틸리티를 사용하지 않습니다.