디렉토리에서 가장 큰 파일 찾기 - 시간이 많이 걸립니다

디렉토리에서 가장 큰 파일 찾기 - 시간이 많이 걸립니다

많은 하위 디렉터리와 N개의 파일이 있는 디렉터리에서 상위 10개의 대용량 파일을 찾으려고 합니다. 내 find명령은 모든 파일을 나열한 다음 정렬 모드로 들어가기 때문에 시간이 오래 걸립니다. 더 빠른 실행이 필요합니다. 가장 최근 실행에서는 목록 자체가 15분 이내에 완료되지 않아 실행을 종료해야 했습니다.

다음 명령을 사용했지만 find모두 충분히 빠르게 실행되지 않고 중단됩니다.

find /opt/app -type f -print 2>/dev/null | xargs ls -lS 2>/dev/null |
    sort -k5,5rn | head -10

find /opt/app -xdev -ls | awk '{print $7, $11}' | " sort -rn "}' | head

find /opt/app -type f -exec ls -lS {} + 2>/dev/null | head -n 10 |
    awk '{ print $5, $9 }'

더 나은 접근 방식은 무엇입니까?

답변1

어떤 경우든 그 안에 있는 모든 디렉터리의 내용을 읽고 를 수행해야 합니다 lstat(). 즉, 어떤 파일이 가장 큰지 결정하기 전에 inode 데이터를 읽어 모든 파일의 파일 크기를 알아내는 것을 의미합니다.

디스크(또는 네트워크 파일 시스템의 경우 네트워크) I/O 액세스(모든 정보가 메모리에 캐시되지 않은 경우)는 가장 많은 시간이 걸리는 부분입니다.

귀하의 방법은 사용자/그룹 ID를 사용자/그룹 이름으로 변환하고, 타임스탬프의 달력 표현을 계산하고, 바이트를 문자로 디코딩하는 등 불필요한 작업을 많이 수행하며 이러한 작업은 CPU와 디스크를 계속 사용하게 합니다. 그러나 디스크 I/O는 여전히 바쁜 상태일 수 있습니다. 병목 현상.

zsh예제의 glob 및 glob 한정자를 사용하면 불필요한 처리 대부분을 건너뛸 수 있습니다.

ls -ldS /opt/apps/**/*(.DOL[1,10])

zsh O파일 목록은 길이(명백한 크기)별로 정렬되지만 여전히 크기별로 정렬 L해야 합니다 . 그렇지 않으면 이름별로 재정렬됩니다. GNU 구현에서는 를 사용하여 정렬을 건너뛸 수 있습니다 . 구현에서는 사람이 읽을 수 있는 크기 (KMGTPE... 1024 기반 접미사 사용) 에 대한 옵션 도 지원했으며 이후 다른 많은 구현에서 복사되었습니다.-SlsSlsls-U-hh

또는 (최신) GNU 도구를 사용하십시오.

(export LC_ALL=C # avoid decoding bytes into characters and
                 # complex sorting orders. Note that it may affect
                 # the ls -l output format though.
 find /opt/apps -type f -printf '%s/%p\0' |
   sort -srnz |
   head -z |
   cut -zd/ -f2- |
   xargs -r0 ls -ldS)

이것이 작업을 더 빠르게 만드는지 확인하세요.

답변2

sort모든 항목이 정렬될 때까지 출력이 제공되지 않습니다. 출력과 새 항목을 반환할 수 없으므로 그게 전부입니다. 내 테스트에서 GNU는 sort정렬 알고리즘을 시작하기에 충분한 출력을 얻자마자 활성화되지만 모든 것이 정렬될 때까지 출력을 지연하므로 둘 다 동일한 기간 sort동안 find활성화됩니다 ( findmore는 초기에 활성화되었고 sort나중에도 활성 상태를 유지하지만, 중복됨).

제가 생각하는 가장 빠른 사용 방법은 find다른 명령이나 텍스트 처리를 최대한 피하는 것입니다. 따라서 여러 번 실행하는 find대신 자체적으로 크기와 이름을 인쇄하십시오 . lsGNU 찾기 사용(파일 이름에 개행 문자가 없다고 가정):

find /opt/app -xdev -type f -printf "%s %p\n" | sort -k1,1n | head

또는 여러 개를 병렬로 실행할 수도 있습니다 find.

(for d in /opt/app/*/; do find "$d" -xdev -type f -printf "%s %p\n" & done; wait) | sort -k1,1n | head

(인터리브 출력으로 인해 해로울 수 있음)

sort그러나 작업이 완료될 때까지 어떤 결과도 얻을 수 없습니다.

답변3

다음 코드는 최상위 대용량 파일을 제공합니다.

ls -l -R <folder path> | grep -v "^d" | awk '{print $5" "$9}' | sort -nrk1,1 | head -n10 | column -t

파일의 전체 경로도 알고 싶다면 다음을 시도해 보세요.

find <folder path> -type f -exec du -a {} + | sort -nr | head -10

답변4

이것이 필요한지 확실하지 않지만 다음과 같습니다.

ls -lR $(비밀번호) |
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=9;다음}
NF&&f{ 인쇄 s"/ "$0 }' | egrep -v '^.|^$|^Total\ ' | awk '{print $6,$1$NF}' |
산출:
13307 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_raid.py
14029 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_eventing.py
15199 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_users.py
20294 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/library/dellemc_configure_idrac_network.py
20851 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/samples/dellemc_get_firmware_inventory.md
35149 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/COPYING.md
49569 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Readme.pdf
65486 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/samples/dellemc_get_system_inventory.md
89526 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Installation_Guide.pdf
438419 /home/pierdolia/repo/Dell-EMC-Ansible-Modules-for-iDRAC/docs/OMAM_1.0.1_Users_Guide.pdf
단 한 가지 단점이 있습니다. 디렉토리에 파일이 너무 많으면 ls가 이를 처리할 수 없으므로 작동하지 않습니다.

내 개인적인 경험에 따르면 find 명령이 이러한 작은 명령보다 작동하는 데 시간이 더 오래 걸리는 것으로 나타났습니다. 예, "최종" 버전이 아니며 축소할 수 있지만 꽤 좋습니다.

PS 첫 번째 AWK를 제거하면 파일 이름만 표시됩니다.

ls -lR $(비밀번호) | egrep -v '^.|^$|^Total\ ' | sort -nk5 |
-rw-rw-r-- 1 pierdolia pierdolia 13307 5월 14일, 13:22 dellemc_configure_raid.py
-rw-rw-r-- 1 pierdolia pierdolia 14029 5월 14일, 13:22 dellemc_configure_idrac_eventing.py
-rw-rw-r-- 1 pierdolia pierdolia 15199 5월 14일, 13:22 dellemc_configure_idrac_users.py
-rw-rw-r-- 1 pierdolia pierdolia 20294 5월 14일 13:22 dellemc_configure_idrac_network.py
-rw-rw-r-- 1 pierdolia pierdolia 20851 5월 14일 13:22 dellemc_get_firmware_inventory.md
-rw-rw-r-- 1 pierdolia pierdolia 35149 5월 14일 13:22 COPYING.md
-rw-rw-r-- 1 pierdolia pierdolia 49569 5월 14일, 13:22 OMAM_1.0.1_Readme.pdf
-rw-rw-r-- 1 pierdolia pierdolia 65486 5월 14일, 13:22 dellemc_get_system_inventory.md
-rw-rw-r-- 1 pierdolia pierdolia 89526 5월 14일, 13:22 OMAM_1.0.1_Installation_Guide.pdf
-rw-rw-r-- 1 pierdolia pierdolia 438419 5월 14일, 13:22 OMAM_1.0.1_Users_Guide.pdf
또는 추가 awk를 추가하십시오.
ls -lR $(비밀번호) | egrep -v '^.|^$|^Total\ ' |Sort-nk5 |Tail-n 10 | awk '{$5,$NF}'
13307 dellemc_configure_raid.py
14029 dellemc_configure_idrac_eventing.py
15199 dellemc_configure_idrac_users.py
20294 dellemc_configure_idrac_network.py
20851 dellemc_get_firmware_inventory.md
35149 copy.md
49569 OMAM_1.0.1_Readme.pdf
65486 dellemc_get_system_inventory.md
89526 OMAM_1.0.1_설치 가이드.pdf
438419 OMAM_1.0.1_Users_Guide.pdf

관련 정보