모든 하위 디렉토리를 검사하고 더 많은 재귀없이 파일이 얼마나 많은지보고해야합니다.
directoryName1 numberOfFiles
directoryName2 numberOfFiles
모든 하위 디렉토리를 검사하고 더 많은 재귀없이 파일이 얼마나 많은지보고해야합니다.
directoryName1 numberOfFiles
directoryName2 numberOfFiles
답변:
이것은 안전하고 휴대 가능한 방식으로 수행됩니다. 이상한 파일 이름으로 혼동되지 않습니다.
for f in *; do [ -d ./"$f" ] && find ./"$f" -maxdepth 1 -exec echo \; | wc -l && echo $f; done
먼저 파일 수를 인쇄 한 다음 디렉토리 이름을 별도의 줄에 인쇄합니다. OP 형식을 유지하려면 추가 형식이 필요합니다 (예 :
for f in *; do [ -d ./"$f" ] && find ./"$f" -maxdepth 1 -exec echo \;|wc -l|tr '\n' ' ' && echo $f; done|awk '{print $2"\t"$1}'
관심있는 특정 서브 디렉토리 세트가있는 경우이를 서브 디렉토리로 교체 할 수 *
있습니다.
이것이 왜 안전한가요? (따라서 스크립트 가치)
파일 이름은를 제외한 모든 문자를 포함 할 수 있습니다 /
. 쉘이나 명령으로 특별히 처리되는 문자가 몇 가지 있습니다. 여기에는 공백, 줄 바꿈 및 대시가 포함됩니다.
for f in *
구문을 사용하면 파일 이름에 관계없이 각 파일 이름을 얻는 안전한 방법입니다.
변수에 파일 이름이 있으면 여전히 같은 것을 피해야 find $f
합니다. 경우 $f
파일 이름을 포함 -test
, find
당신은 그냥 준 옵션에 대해 불평한다. 이를 피하는 방법 ./
은 이름 앞에 사용하는 것입니다 . 이런 식으로 같은 의미를 갖지만 더 이상 대시로 시작하지 않습니다.
줄 바꿈과 공백도 문제입니다. $f
파일 이름으로 "hello, buddy"가 포함 된 경우 find ./$f
입니다 find ./hello, buddy
. 당신은 이야기하고 find
보고 ./hello,
하고 buddy
. 해당 사항이 존재하지 않으면 불만을 제기하며을 (를) 찾지 않습니다 ./hello, buddy
. 이것은 피하기 쉽습니다-변수 주위에 따옴표를 사용하십시오.
마지막으로 파일 이름에 줄 바꿈이 포함될 수 있으므로 파일 이름 목록에서 줄 바꿈을 계산하면 작동하지 않습니다. 개행 문자가있는 모든 파일 이름에 대해 추가 개수를 얻게됩니다. 이를 피하려면 파일 목록에서 줄 바꿈을 계산하지 마십시오. 대신 단일 파일을 나타내는 줄 바꿈 (또는 다른 문자)을 계산하십시오. 이것이 find
명령이 단순 -exec echo \;
하지 않은 이유 -exec echo {} \;
입니다. 파일 크기를 조정하기 위해 새 줄 하나만 인쇄하고 싶습니다.
-mindepth 1
-printf '\n'
대신에 사용할 수도 있습니다 -exec echo
.
-printf
있지만 FreeBSD에서 작동하도록하려는 경우가 아닙니다.
표준 Linux 솔루션을 찾고 있다고 가정하면 비교적 간단한 방법은 다음과 find
같습니다.
find dir1/ dir2/ -maxdepth 1 -type f | wc -l
어디는 find
A를, 지정된 두 개의 하위 디렉토리를 통과 -maxdepth
추가 재귀를 방지 1 만 (파일보고 -type f
) 줄 바꿈으로 구분합니다. 그런 다음 결과를 파이프하여 wc
해당 행 수를 계산합니다.
find . -maxdepth 1 -type d
출력을 어떻게 결합 할 수 있습니까?
find $dirs ...
하거나 (b) 하나의 상위 레벨 디렉토리에만있는 경우 해당 디렉토리에서 find */ ...
-exec echo
찾기 명령에 추가 하십시오-파일 이름을 표시하지 않고 줄 바꿈 만합니다.
"재귀없이" directoryName1
는 하위 디렉토리 가있는 경우 하위 디렉토리의 파일을 계산하지 않으려는 것을 의미 합니까? 그렇다면 표시된 디렉토리의 모든 일반 파일을 계산하는 방법입니다.
count=0
for d in directoryName1 directoryName2; do
for f in "$d"/* "$d"/.[!.]* "$d"/..?*; do
if [ -f "$f" ]; then count=$((count+1)); fi
done
done
참고 그 -f
테스트를 수행 두 함수 : 그것은 globs와 하나와 일치하는 엔트리가 상기 일반 파일인지를 테스트하고합니다 (globs와의 하나는 아무것도 is¹ 같은 패턴 나머지와 일치하지 않는 경우)이 엔트리가 일치 여부를 테스트한다. 당신은 유형과 관계없이 주어진 디렉토리에있는 모든 항목을 계산하려면, 대신 -f
에-e
.
Ksh에는 패턴과 일치하는 파일이없는 경우 패턴을 도트 파일과 일치시키고 빈 목록을 생성하는 방법이 있습니다. ksh에서는 다음과 같은 일반 파일을 계산할 수 있습니다.
FIGNORE='.?(.)'
count=0
for x in ~(N)directoryName1/* ~(N)directoryName2/*; do
if [ -f "$x" ]; then ((++count)); fi
done
또는 모든 파일은 다음과 같습니다.
FIGNORE='.?(.)'
files=(~(N)directoryName1/* ~(N)directoryName2/*)
count=${#files}
Bash는 이것을 더 간단하게 만드는 다른 방법을 가지고 있습니다. 일반 파일을 세려면
shopt -s dotglob nullglob
count=0
for x in directoryName1/* directoryName2/*; do
if [ -f "$x" ]; then ((++count)); fi
done
모든 파일을 세려면 :
shopt -s dotglob nullglob
files=(directoryName1/* directoryName2/*)
count=${#files}
평소와 같이 zsh에서는 훨씬 간단합니다. 일반 파일을 세려면
files=({directoryName1,directoryName2}/*(DN.))
count=$#files
변경 (DN.)
에(DN)
모든 파일 려면로 하십시오.
¹ 각 패턴이 일치한다는 점에 유의하십시오. 그렇지 않으면 결과가 꺼질 수 있습니다 (예 : 숫자로 시작하는 파일을 세는 경우 for x in [0-9]*; do if [ -f "$x" ]; then …
이라는 파일이있을 수 있으므로 수행 할 수 없음 [0-9]foo
).
을 바탕으로 카운트 스크립트 , 숀의 대답 과 배쉬 트릭 확실히 심지어 파일 이름 줄 바꿈이 한 줄에 사용할 수있는 형태로 인쇄로 만들려면 :
for f in *
do
if [ -d "./$f" ]
then
printf %q "$f"
printf %s ' '
find "$f" -maxdepth 1 -printf x | wc -c
fi
done
printf %q
인용 된 버전의 문자열, 즉 한 줄짜리 문자열을 인쇄하여 Bash 스크립트에 넣어 줄 바꿈 및 기타 특수 문자를 포함한 리터럴 문자열로 해석 할 수 있습니다. 예를 들어 echo -n $'\tfoo\nbar'
vs를 참조하십시오 printf %q $'\tfoo\nbar'
.
이 find
명령은 각 파일에 대해 단일 문자를 인쇄 한 다음 줄을 세지 않고 문자를 세는 방식으로 작동합니다.
여기에 사용하여 결과를 얻을 수있는 "무차별"-ish 방법 find
, echo
, ls
, wc
, xargs
와 awk
.
find . -maxdepth 1 -type d -exec sh -c "echo '{}'; ls -1 '{}' | wc -l" \; | xargs -n 2 | awk '{print $1" "$2}'
for i in `ls -1`; do echo $i : `ls -1 $i|wc -l`; done
find
Bash가 할 때 왜 사용하고 싶 습니까?(shopt -s dotglob; for dir in */; do all=("$dir"/*); echo "$dir: ${#all[@]}"; done)
: 모든 디렉토리에 대해 해당 디렉토리의 항목 수 (숨겨진 점 파일 포함.
및 제외..
)