"documents/"에 얼마나 많은 하위 디렉터리와 파일이 있는지 계산해 보세요.

"documents/"에 얼마나 많은 하위 디렉터리와 파일이 있는지 계산해 보세요.

게임셸을 통해 리눅스를 배우고 있어요.

제목에서 알 수 있듯이 "documents/"에서 하위 디렉터리와 파일 수를 찾아야 합니다. 이 명령은 제대로 작동하지만 정답은 아닙니다. 이것은 내 명령입니다:

find documents/ -type f | wc -l | awk '{print $1}' 

내가 뭘 잘못했나요?

답변1

포함(Contains)은 -type f디렉터리가 아닌 파일만 포함한다는 의미입니다. 이 섹션을 제거하고 더 잘 작동하는지 확인해 보세요.

| awk '{ print $1 }'이 섹션을 제거하여 실제로 필요한지 확인할 수 있습니다.

답변2

귀하의 명령은 출력의 줄 수만 계산합니다 find. 이 명령은 디렉터리 안이나 디렉터리 아래에 있는 일반 파일의 경로 이름 find만 출력합니다 .documents

디렉터리 안이나 아래에 있는 일반 파일과 디렉터리의 수를 계산하려면 셸에서 다음을 수행 documents할 수 있습니다 .zsh

set -- documents/**/*(DN/) documents/**/*(DN.)
printf 'There are %d regular files and directories in or under "documents"\n' "$#"

이 세트위치 매개변수( $1등)은 두 개의 파일 이름 와일드카드 패턴의 합을 확장한 결과입니다 $2. 첫 번째는 모든 일반 파일과 일치하고 두 번째는 디렉터리(숨겨져 있는지 여부에 관계없이)와 일치합니다. 이 패턴은 "재귀적으로" 하위 디렉터리와 일치합니다.documents/**/*(DN/)documents/**/*(DN.)**

위치 매개변수가 설정되면 특수 변수가 $#이러한 매개변수의 수를 보유합니다.

쉘 에서는 bash지원되지 않습니다.글로벌 예선 (DN/)그리고 (DN.)루프를 사용할 수 있습니다.

shopt -s globstar dotglob nullglob

count=0
for pathname in documents/**/*; do
    if [[ -f $pathname ]] || [[ -d $pathname ]]; then
       [[ ! -h $pathname ]] && count=$(( count + 1 ))
    fi
done

printf 'There are %d regular files and directories in or under "documents"\n' "$count"

이는 zsh변형보다 조금 더 복잡하지만 이해하기 쉽습니다. 먼저 **숨겨진 이름을 계산하고 일치하는 항목이 없으면 패턴이 비어 있는 것으로 확인될 수 있도록 사용할 수 있는 몇 가지 셸 옵션을 설정합니다 (마지막 두 개는 Dglob 한정자의 the 및 the 와 동일합니다).Nzsh

루프 내에서 현재 경로 이름이 심볼릭 링크가 아닌 일반 파일인지 디렉터리인지 테스트합니다. 일반 파일이나 디렉터리라면 개수로 계산됩니다.

에서는 sh다음으로 전환해야 합니다 find.

find documents \( -type f -o -type d \) -exec echo . \; | wc -l

우리는 안이나 아래에서 일반 파일이나 디렉토리를 찾고 documents, 그러한 각각에 대해 한 줄에 별도의 점을 출력합니다. 그런 다음 wc -l생성된 행 수를 계산합니다. 이렇게 하면 개행 문자가 포함된 파일 이름을 여러 번 계산하는 것을 방지할 수 있습니다.

이 변형은 documents디렉터리 자체도 계산합니다.

답변3

공백, 줄 바꿈 또는 문자가 포함될 수 있는 파일 이름을 처리하는 가장 안전한 방법입니다.아무것각 파일 이름을 단일 안전 문자(예: X)로 변환하는 것입니다.

find를 사용하면 발견된 모든 파일/디렉토리에 대해 명령을 실행할 수 있습니다.

find documents/ -type f -exec printf X \; ; echo

X이렇게 하면 파일 수만큼 포함된 문자열이 생성됩니다 ( 디렉터리 수를 계산 f하도록 변경됨). d이를 숫자로 변환하려면 명령 결과를 캡처하고 결과 문자열의 크기를 인쇄할 수 있습니다.

$ str="$(find documents -type d -exec printf X \;)"
$ echo "${#str}"
23

또는 바이트 수를 직접 계산합니다(사용된 유일한 문자는 문자이므로 문자와 동일 X).

$ find testit -type d -exec printf X \; | wc -c

find 명령은 도트 파일 수를 계산하고 기호 링크(-L 사용)를 따라갈 수도 있고 그렇지 않을 수도 있습니다(기본값). 기본적으로 도트 파일을 피하고 심볼릭 링크(bash 4.3 현재 디렉토리가 아닌 파일에 대한)를 따르는 것이 문제가 되지 않으면 다음을 사용할 수 있습니다.와일드카드

$ ( shopt -s globstar; set -- documents/**/*/; echo "$#" )
23

디렉토리의 경우:

$ ( shopt -s globstar; set -- documents/**/*; echo "$#" )
65

모든 파일에 대해그리고디렉토리(디렉토리 기호 링크를 따르지 않음)

관련 정보