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
, find
in -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