모든 하위 디렉토리에서 파일 수를보고하는 방법은 무엇입니까? 많은 재귀없이 파일이

모든 하위 디렉토리를 검사하고 더 많은 재귀없이 파일이 얼마나 많은지보고해야합니다.

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 {} \;입니다. 파일 크기를 조정하기 위해 새 줄 하나만 인쇄하고 싶습니다.


답변

표준 Linux 솔루션을 찾고 있다고 가정하면 비교적 간단한 방법은 다음과 find같습니다.

find dir1/ dir2/ -maxdepth 1 -type f | wc -l

어디는 findA를, 지정된 두 개의 하위 디렉토리를 통과 -maxdepth추가 재귀를 방지 1 만 (파일보고 -type f) 줄 바꿈으로 구분합니다. 그런 다음 결과를 파이프하여 wc해당 행 수를 계산합니다.


답변

“재귀없이” 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, xargsawk.

find . -maxdepth 1 -type d -exec sh -c "echo '{}'; ls -1 '{}' | wc -l" \; | xargs -n 2 | awk '{print $1" "$2}'


답변

for i in *; do echo $i; ls $i | wc -l; done


답변

    for i in `ls -1`; do echo $i : `ls -1 $i|wc -l`; done