`find보다 빠른 것이 있습니까? | wc -l`는 디렉토리의 파일을 계산합니까?


8

드물게 디렉토리의 파일 수를 세어야 할 필요는 없으며 때로는 수백만에 달합니다.

그냥 열거하고 계산하는 것보다 더 좋은 방법이 find . | wc -l있습니까? ext3 / 4에서 I / O 집약도가 낮은 파일 시스템 호출이 있습니까?


3
파일뿐만 아니라 디렉토리도 세고 있습니다. 파일 만 계산하려면 기호 링크 및 일반 파일을 계산하려면 "find. -type f | wc -l"을 사용하고 "find. -type f-또는 -type l | wc -l"
FSMaxB를 사용하십시오.

디렉토리는 장치, 심볼릭 링크 및 소켓과 같은 일종의 파일입니다. 일반 파일은 파일의 하위 집합입니다.
Toby Speight

1
당신이 제공하는 예제는 재귀 카운트 를 원한다는 것을 제안 합니다 find -maxdepth 1. 현재 접근 방식에서는 개행 문자가 포함 된 이름을 두 번 계산합니다.
Toby Speight

답변:


13

기본 속도 향상은 아니지만 최소한 :)

find . -printf \\n | wc -l

실제로 파일 이름 목록을 전달할 필요는 없으며 개행만으로 충분합니다. 이 변형은 디렉토리가 RAM에 캐시 될 때 우분투 12.04.3에서 약 15 % 빠릅니다. 또한이 변형은 개행을 포함하는 파일 이름에서 올바르게 작동합니다.

흥미롭게도이 변종은 위의 것보다 약간 느린 것 같습니다.

find . -printf x | wc -c

특별한 경우-그러나 정말 빠릅니다

디렉토리가 자체 파일 시스템에있는 경우 간단히 inode를 계산할 수 있습니다.

df -i .

계산 된 것 이외의 다른 디렉토리에있는 디렉토리 및 파일의 수가 크게 변하지 않으면 현재 df -i결과 에서이 알려진 숫자를 빼기 만하면 됩니다. 이 방법으로 파일과 디렉토리를 매우 빠르게 계산할 수 있습니다.


"이 변종은 약 15 % 빠릅니다 ..."시간을 내기 위해 사용하는 편리한 트릭이 있는지 궁금합니다.
Brian Z

4
@BrianZ : 시간 앞에 명령을 추가하여 명령 시간을 지정할 수 있습니다. time find /usr/src/ -printf \\n | wc -l을 사용하여 실행 사이에 캐시를 지울 수 있습니다.sudo sync && sudo sysctl -w vm.drop_caches=3
MattPark

따라서 캐싱없이 처음 두 가지 옵션 중 하나를 사용하여 속도가 일관되게 2 % 증가했습니다. 예, 정말 멋진 방법입니다. 환경이 설정되어 있다면 inode를 계산하는 것이 가장 좋습니다. 나는 그것을 고려하지 않았다.
MattPark

가요 -printf x와 동일하게 의미 -printf '\0'? 문서에 언급되어 있지 않습니다.
CMCDragonkai

@CMCDragonkai : 동작 -printf은 지시문의 의미가 printf()다르다는 주요 차이점을 제외하고 C 의 함수 와 유사하게 작동 %합니다. 발견 된 모든 파일에 대해 조치가 호출됩니다. 즉, 발견 된 모든 파일에 -printf x대해 문자 x를 인쇄하고 (시도하십시오!) 발견 된 모든 파일에 -printf '\0'대해 문자 NULL (ASCII 코드 0)을 인쇄합니다. -printf '\0'특별한 의미가 없습니다. wc -c이 답변 의 예에서 두 가지 모두 동일하게 작동합니다 .
pabouk

3

나는 그 목적을 위해 ffcnt 를 썼습니다 . fiemapioctl을 사용하여 디렉토리 자체의 실제 오프셋을 검색 한 다음 무작위 순차 액세스를 줄이기 위해 여러 순차 패스에서 디렉토리 순회를 스케줄링합니다. 실제로 속도 향상 find | wc 여부는 몇 가지 요인 에 따라 다릅니다.

  • 파일 시스템 유형 : fiemapioctl 을 지원하는 ext4와 같은 파일 시스템 이 가장 유리합니다.
  • 랜덤 액세스 속도 : HDD는 SSD보다 훨씬 많은 이점을 제공합니다
  • 디렉토리 레이아웃 : 중첩 된 디렉토리의 수가 많을수록 최적화 가능성이 높아짐

(재) 마운트가 메타 데이터 업데이트를 유발할 경우 속도를 향상 시키 relatime거나 nodiratime모든 방법에서 속도를 향상시킬 수도 있습니다.


마지막 문장은 유용한 팁입니다! 프로그램 작동 방식에 대한 요약을 추가하면 프로그램 링크가 향상 될 것입니다. 링크 된 리소스에 문제가 발생하는 경우 자체적으로 완전한 답변을 선호합니다 (물론 링크도 그대로 유지).
Toby Speight

2

실제로 내 시스템 (Arch Linux)에서이 명령

   ls -A | wc -l

위의 모든 것보다 빠릅니다.

   $ time find . | wc -l
  1893

   real    0m0.027s
   user    0m0.004s
   sys     0m0.004s
   $ time find . -printf \\n  | wc -l
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time find . -printf x  | wc -c
   1893

   real    0m0.009s
   user    0m0.000s
   sys     0m0.008s
   $ time ls -A | wc -l
   1892

   real    0m0.007s
   user    0m0.000s
   sys     0m0.004s

그래도 ls의 문제는 /bin/ls: Argument list too longglobbing을 사용하는 경우 와 같이 종종 무언가를 반환 하지만 다시 찾기와 같이 재귀 적으로 작동 할 수 있다는 것입니다.
MattPark

그것에 대해 언급하는 것은 너무 늦게 보이지만 ls -A, 현재 디렉토리에있는 파일 만 나열하면 인수 find없이 -maxdepth 1모든 하위 디렉토리를 재귀 적으로 검색합니다.
Luciano
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.