재귀적 파일 수 가져오기(예: "du", 크기 대신 파일 수)

재귀적 파일 수 가져오기(예: "du", 크기 대신 파일 수)

rsnapshot의 성능 문제로 인해 많은 수의 파일이 포함된 디렉터리를 반복적으로 식별하고 싶습니다. 문제는 파일 크기가 아니라 특정 하위 디렉터리에 있는 파일 수인 것 같습니다. 세대 수(daily.0, daily.1, ...)가 휘발성이 아니고 전체에 비해 거의 변하지 않기 때문입니다. 파일 수.

Unix 명령이 파일 크기의 합계가 아닌 파일 수만 반환한다면 du이것이 바로 제가 원하는 것입니다 .

나는 이미 하나 가지고 있습니다파일 수를 출력하는 bash 스크립트모두직접(하위 디렉토리로 재귀) 하지만 항상 대기하면서 점점 더 깊숙히 파고 들어가야 하기 때문에 사용하기 번거롭습니다.

또한 하나를 찾았습니다.스크립트를 더 깊이 파고들기이지만 하위 디렉터리의 파일 수는 요약하지 않습니다. 하위 디렉터리가 아닌 이 디렉터리의 파일 수만 표시됩니다.

반드시 쉘 스크립트일 필요는 없습니다. 저는 Ruby, Python, Perl, JavaScript 등과 같은 다른 스크립팅 언어에 개방적입니다.

예:

dir1/
   file1
   subdir1/
       file2, file3, file4, file5
   subdir2/
       file6, file7, file8
       subdir3/
           file9
dir2/
    fileA, fileB

원하는 출력(하위 디렉토리를 나열하고 맨 위로 요약):

4   dir1/subdir1
1   dir1/subdir2/subdir3
4   dir1/subdir2
9   dir1/
2   dir2/

난 무엇인가?아니요원하는 것(총계만 나열됨):

9   dir1/
2   dir2/

그리고아니요.( 디렉토리에 있는 파일 수만 나열 ):

4   dir1/subdir1
1   dir1/subdir2/subdir3
3   dir1/subdir2
1   dir1/
2   dir2/

답변1

다음과 같이 시도해 보세요.

find . -type f | perl -aF/ -lne 'for (my $i=0; $i < @F-1; ++$i) { print join("/",@F[0...$i]); }' | sort | uniq -c

find . -type f문서 인쇄:

./dir1/subdir2/file8
./dir1/subdir2/file7
./dir1/subdir2/subdir3/file9
./dir1/subdir2/file6
./dir1/file1
...

perl -aF/ -lne 'for (my $i=0; $i < @F-1; ++$i) { print join("/",@F[0...$i]); }'각 파일 이름을 ./a/b/c일련의 디렉터리로 변환합니다 .../a./a/b

노트:

파일 이름에 개행 문자가 있으면 작동하지 않습니다. 각 디렉토리에 대해 in hash -print0, findin -0및 put 카운터를 사용할 수 있습니다 .perl

편집하다:

@Gilles의 글에서 영감을 받음답변:

find . -depth -print0 |
perl -0 -ne '
my $depth = tr!/!/!;
for (my $i = $prev_depth; $i <= $depth; ++$i) { $totals[$i] = 0; }
if ( -f $_ ) {
  for (my $i = 0; $i <= $depth; ++$i) { ++$totals[$i]; }
} else {
  print "$totals[$depth]\t$_\n";
}
$prev_depth = $depth;
'

파일 이름의 줄 바꿈에 적용됩니다. 빈 디렉토리에서 작동합니다. 추가 기능이 필요하지 않습니다 sort | uniq -c.

답변2

find(디렉토리의 하위 디렉터리에 있는 모든 파일을 포함하여 디렉터리의 모든 파일을 반복하는 데 사용할 수 있음) 및 wc(파일의 줄 수를 계산하는) 단일 줄은 어떻 습니까 ?

find <directory> | wc

<directory>모든 파일의 개수를 계산하려는 디렉터리는 어디에 있습니까? 그러면 세 개의 숫자가 인쇄됩니다. 첫 번째 숫자는 find에서 반환된 행 수입니다. 기본적으로 파일과 디렉터리를 찾는다고 생각하므로 총 파일 및 디렉터리 수(자체 포함)가 제공됩니다 find.<directory><directory>

find이는 매우 유연한 명령입니다. 실제로 파일에만 관심이 있고 디렉터리 수는 계산하고 싶지 않다면

find <directory> -type f | wc

작동합니다. 예를 들어, 깊이에 관계없이 현재 디렉터리에 포함된 모든 파일의 수를 계산하려면 다음을 수행할 수 있습니다.

find . -type f | wc

주의 사항: find기본적으로 심볼릭 링크 등은 따르지 않습니다. 파일이 다양한 파일 시스템에 있거나 자신이 소유한 파일 시스템에 있는 경우 find거의 모든 것을 처리하도록 설정할 수 있으므로 매뉴얼 페이지를 확인해야 합니다. 또한 이것은 wc줄 수이므로 이름에 줄바꿈이 포함된 파일이 있는 경우(기술적으로는 가능하지만 일반적으로 내가 아는 한 좋은 생각은 아님) 이와 유사한 내용이 있으면 흥미로운 답변을 얻을 수 있습니다.

답변3

내 의견에 따르면 다음과 같은 변형이 귀하의 요구에 적합할 수 있습니다.

find . -depth -type d -exec /bin/sh -c 'printf "%5d %s\n" "$(find {} -type f -printf . | wc -c)" "{}"' \;

(제가 더 깊은 하위 디렉토리의 결과를 여러 번 계산하고 파일 시스템 캐시가 어느 시점에서 트리의 전체 메타데이터를 갖고 매번 새로운 쉘을 생성할 것으로 예상하므로 올바르게 실행된 여단은 확실히 저를 올바르게 쏠 것입니다. 그러나 이것은 시작.)

귀하의 예제 구조를 바탕으로 다음을 얻습니다.

    4 ./dir1/subdir1
    1 ./dir1/subdir2/subdir3
    4 ./dir1/subdir2
    9 ./dir1
    2 ./dir2
   11 .

(현재 작업 디렉토리를 제외하려면 external find .로 변경 find *하거나find . -mindepth 1

관련 정보