게임셸을 통해 리눅스를 배우고 있어요.
제목에서 알 수 있듯이 "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
변형보다 조금 더 복잡하지만 이해하기 쉽습니다. 먼저 **
숨겨진 이름을 계산하고 일치하는 항목이 없으면 패턴이 비어 있는 것으로 확인될 수 있도록 사용할 수 있는 몇 가지 셸 옵션을 설정합니다 (마지막 두 개는 D
glob 한정자의 the 및 the 와 동일합니다).N
zsh
루프 내에서 현재 경로 이름이 심볼릭 링크가 아닌 일반 파일인지 디렉터리인지 테스트합니다. 일반 파일이나 디렉터리라면 개수로 계산됩니다.
에서는 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
모든 파일에 대해그리고디렉토리(디렉토리 기호 링크를 따르지 않음)