각 하위 디렉토리의 파일 수


22

BASH 명령을 사용하여 디렉토리의 각 하위 디렉토리에있는 파일 수만 나열하고 싶습니다.

디렉토리에있는 예 /tmp가있다 dir1, dir2... 나는보고 싶습니다

`dir1` : x files 
`dir2` : x files ...

답변:


33

디렉토리와 다른 유형이 아닌 재귀 파일 수만 원한다고 가정하면 다음과 같이 작동합니다.

find . -maxdepth 1 -mindepth 1 -type d | while read dir; do
  printf "%-25.25s : " "$dir"
  find "$dir" -type f | wc -l
done

또한 "find : warning : 옵션이 아닌 인수 -type 뒤에 -maxdepth 옵션을 지정했지만 옵션이 위치에 있지 않습니다 (-maxdepth는 이전에 지정된 테스트와 그 뒤에 지정된 테스트에 영향을 미칩니다."옵션을 지정하십시오). 다른 주장 앞에 "
jldupont

2
지금까지 제공된 두 대답 모두 이름에 개행 문자가 포함 된 파일이있을 가능성이없는 경우 잘못된 결과를 제공합니다. 당신은 그것을 처리 할 수 ​​있습니다 find... -print0 | xargs -0....
Scott

@jldupont : ʻtype d´ 전에 깊이 인수를 이동하면 답을 편집했습니다.
Thor

예,이 우수한 솔루션이 외부 변수를 사용 하지 않으므로 작동 할 것이라는 정보를 추가하겠습니다 bash alias!!
syntaxerror

빠르고, 배관 sort -rn -k 2,2 -t$':'하면 DESC 목록을 얻을 수 있습니다
Andre Figueiredo

14

이 과제는 나를 매료 시켜서 스스로 해결책을 찾고 싶었습니다. while 루프가 필요하지 않습니다. 수도 빠른 실행 속도합니다. 말할 필요도없이 Thor의 노력으로 세부 사항을 이해하는 데 많은 도움이되었습니다.

여기 내 것이 있습니다 :

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "{} : $(find "{}" -type f | wc -l)" file\(s\)' \;

그것은보기보다 훨씬 강력하기 때문에 이유가 겸손 해 보입니다. :-)

그러나 이것을 .bash_aliases파일에 포함 시키려면 다음과 같아야합니다.

alias somealias='find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '\''echo "{} : $(find "{}" -type f | wc -l)" file\(s\)'\'' \;'

중첩 된 작은 따옴표를 처리하기가 매우 까다 롭습니다 . 그리고 아니요, 인수에 큰 따옴표를 사용할 수 없습니다sh -c .


각 디렉토리에 대해 / bin / sh를 호출 할 때 속도가 느립니다. 로 확인할 수 있습니다 strace -fc script. 귀하의 버전은 약 70 % 더 많은 시스템 호출을합니다. 더 짧은 코드의 경우 +1 :-)
Thor

1
이것에 의해 영감을 얻은; 파일 find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "$(find "{}" -type f | wc -l)" {}' \; | sort -nr
개수로

7
find . -type f | cut -d"/" -f2 | uniq -c

현재 폴더의 폴더와 파일을 아래에있는 파일 수와 함께 나열합니다. 빠르고 유용한 IMO. (파일 수가 1로 표시됨).


1
작동 방식에 대한 간단한 설명은 어떻습니까? :)
C0deDaedalus

1
감사합니다! | sort -rn파일 수별로 하위 디렉토리를 정렬 하기 위해 추가 할 수 있습니다.
Dennis Golomazov

1

찾기를 사용하는 것은 재귀 적으로 계산하고 싶지만 특정 디렉토리에서 직접 파일 수를 원한다면 갈 수있는 방법입니다.

ls dir1 | wc -l


나는 거기에있는 1000 개의 디렉토리 각각에 대해 이것을하고 싶지 않다 ...
jldupont

그런 다음 xargs를 사용하십시오. ls -d */ | xargs -n1 ls | wc -l(하지만 이미 작동하는 경우 수락 한 대답을 사용하십시오! 이것은 단지 지금 알고 있습니다.)
jrajav

귀하의 제안은 몇 초 안에 결과를 보여주지 않았지만 내가 수락 한 대답은 그랬습니다.
jldupont

@jrajav이 접근법은 공백이있는 디렉토리에서는 절대적으로 실패합니다. 이것이 find중요한 이유 입니다. (혼자 -print0xargs -0, 이미 다른 답변에서 Scott이
지적함

1
find . -mindepth 1 -type d -print0 | xargs -0 -I{} sh -c 'printf "%4d : %s\n" "$(find {} -type f | wc -l)" "{}"'

하위 디렉토리의 파일 수를 세고이 명령을 사용해야하는 경우가 종종 있습니다. 카운트가 먼저 나타나는 것을 선호합니다.


0

내가 사용하는 것 ... 이렇게하면 매개 변수로 제공하는 모든 하위 디렉토리의 배열이 만들어집니다. 모든 서브 디렉토리가 처리 될 때까지 서브 디렉토리 및 동일한 서브 디렉토리의 수를 인쇄하십시오.

#!/bin/bash    
directories=($(/bin/ls -l $1 | /bin/grep "^d" | /usr/bin/awk -F" " '{print $9}'))

for item in ${directories[*]}
    do
        if [ -d "$1$item" ]; then
            echo "$1$item"
            /bin/ls $1$item | /usr/bin/wc -l
        fi
    done

0

이 파이썬 코드를 사용할 수 있습니다. 다음을 실행하여 인터프리터를 부팅 python3하고 붙여 넣습니다.

folder_path = '.'
import os, glob
for folder in sorted(glob.glob('{}/*'.format(folder_path))):
    print('{:}: {:>8,}'.format(os.path.split(folder)[-1], len(glob.glob('{}/*'.format(folder)))))

또는 중첩 카운트의 재귀 버전 :

import os, glob
def nested_count(folder_path, level=0):
    for folder in sorted(glob.glob('{}/'.format(os.path.join(folder_path, '*')))):
        print('{:}{:}: {:,}'.format('    '*level, os.path.split(os.path.split(folder)[-2])[-1], len(glob.glob(os.path.join(folder, '*')))))
        nested_count(folder, level+1)
nested_count('.')

출력 예 :

>>> figures: 5
>>> misc: 1
>>> notebooks: 5
>>>     archive: 65
>>>     html: 12
>>>     py: 12
>>>     src: 14
>>> reports: 1
>>>     content: 6
>>> src: 1
>>>     html_download: 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.