파일에 보유 된 경로 목록을 구문 분석하려면 basename을 사용하십시오. f -name “*”

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


답변

xargswith 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

이것은 외부 유틸리티를 사용하지 않습니다.


답변