명령 프롬프트에서 파일 크기 분포 생성


16

몇 백만 개의 파일이있는 파일 시스템이 있는데 특정 디렉토리에서 파일 크기의 재귀를 반복적으로보고 싶습니다. 나는 이것이 bash / awk fu로 완전히 가능하다고 생각하지만 손을 사용할 수 있습니다. 기본적으로 다음과 같은 것을 원합니다.

1KB: 4123
2KB: 1920
4KB: 112
...
4MB: 238
8MB: 328
16MB: 29138
Count: 320403345

루프가 주어지면 너무 나쁘지 않아야한다고 생각하고 일부 조건부 log2 파일은 foo를 나타내지 만 거기에 도달 할 수는 없습니다.

관련 질문 : x 바이트보다 크거나 작은 파일을 어떻게 찾을 수 있습니까? .

답변:


22

이것은 꽤 잘 작동하는 것 같습니다 :

find . -type f -print0 | xargs -0 ls -l | awk '{size[int(log($5)/log(2))]++}END{for (i in size) printf("%10d %3d\n", 2^i, size[i])}' | sort -n

결과는 다음과 같습니다.

         0   1
         8   3
        16   2
        32   2
        64   6
       128   9
       256   9
       512   6
      1024   8
      2048   7
      4096  38
      8192  16
     16384  12
     32768   7
     65536   3
    131072   3
    262144   3
    524288   6
   2097152   2
   4194304   1
  33554432   1
 134217728   4
여기서 왼쪽의 숫자는 해당 값에서 해당 값의 두 배까지 범위의 하한이고 오른쪽의 숫자는 해당 범위의 파일 수입니다.


재귀적이고 디렉토리 계산을 수행하지 않도록 ls 대신 find를 사용하도록 답변을 편집했습니다. 누구든지 왼쪽 열 출력을 예쁘게하고 싶습니까?
notpeter

그러나 원래의 질문은 그래서는 변경 확인 아니다 "특정 디렉토리에있는 파일 크기 분포"에 대해이었다 lsA를 find. 나는 그것을 원래대로 되돌려 놓았습니다.
garyjohn

@notpeter : 죄송합니다. 질문 작성자로 인식하지 못했습니다. 재귀 적으로 검색하도록 답변을 변경했습니다. 그러나 내 시스템에서는을 사용하는 xargs것이 훨씬 빠르 -exec므로 해당 방법을 사용했습니다.
garyjohn

1
걱정 마. 이제 의견을 삭제할 수 있습니다. 항상 정답 인 척합니다. ;)
notpeter

14

garyjohn의 답변을 바탕으로 다음은 하나의 라이너로 출력을 사람이 읽을 수 있도록 형식화합니다.

find . -type f -print0 | xargs -0 ls -l | awk '{ n=int(log($5)/log(2)); if (n<10) { n=10; } size[n]++ } END { for (i in size) printf("%d %d\n", 2^i, size[i]) }' | sort -n | awk 'function human(x) { x[1]/=1024; if (x[1]>=1024) { x[2]++; human(x) } } { a[1]=$1; a[2]=0; human(a); printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }'

확장 버전은 다음과 같습니다.

find . -type f -print0                                                   \ 
 | xargs -0 ls -l                                                        \
 | awk '{ n=int(log($5)/log(2));                                         \
          if (n<10) n=10;                                                \
          size[n]++ }                                                    \
      END { for (i in size) printf("%d %d\n", 2^i, size[i]) }'           \
 | sort -n                                                               \ 
 | awk 'function human(x) { x[1]/=1024;                                  \
                            if (x[1]>=1024) { x[2]++;                    \
                                              human(x) } }               \
        { a[1]=$1;                                                       \ 
          a[2]=0;                                                        \
          human(a);                                                      \
          printf("%3d%s: %6d\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }' 

처음 awk에는 1kb 미만의 모든 파일을 한곳에 수집하기 위해 최소 파일 크기를 정의했습니다. 두 번째로 awk, human(x)사람이 읽을 수있는 크기를 만들기 위해 함수 가 정의됩니다. 이 부분은 여기에 답변 중 하나를 기반으로합니다 : /unix/44040/a-standard-tool-to-convert-a-byte-count-into-human-kib-mib-etc -like-du-ls1

샘플 출력은 다음과 같습니다.

  1k:    335
  2k:     16
 32k:      5
128k:     22
  1M:     54
  2M:     11
  4M:     13
  8M:      3

2

이 시도:

find . -type f -exec ls -lh {} \; | 
 gawk '{match($5,/([0-9.]+)([A-Z]+)/,k); if(!k[2]){print "1K"} \
        else{printf "%.0f%s\n",k[1],k[2]}}' | 
sort | uniq -c | sort -hk 2 

출력 :

 38 1K
 14 2K
  1 30K
  2 62K
  12 2M
  2 3M
  1 31M
  1 46M
  1 56M
  1 75M
  1 143M
  1 191M
  1 246M
  1 7G

설명 :

  • find . -type f -exec ls -lh {} \;: 충분히 간단하고 현재 디렉토리에서 파일을 찾아서 실행하십시오 ls -lh.

  • match($5,/([0-9.]+)([A-Z]+)/,k); : 파일 크기를 추출하고 각 일치 항목을 배열에 저장합니다. k .

  • if(!k[2]){print "1K"}: k[2]undefined 인 경우 파일 크기는 <1K입니다. 작은 크기에 신경 쓰지 않는다고 상상하기 때문에 스크립트가 인쇄됩니다.1K 크기가 <= 1K 인 모든 파일에 대해 합니다.

  • else{printf "%.0f%s\n",k[1],k[2]} : 파일이 1K보다 큰 경우 파일 크기를 가장 가까운 정수로 반올림하고 수정 자 (K, M 또는 G)와 함께 인쇄하십시오.

  • sort | uniq -c : 인쇄 된 각 줄 (파일 크기)의 발생 횟수를 계산합니다.

  • sort -hk 2: 사람이 읽을 수있는 형식으로 두 번째 필드에 따라 정렬합니다. 이 방법 7G은 다음에 정렬 8M됩니다.


나는 설명을 고맙게 생각한다. 그것을 이해하려는 사람들에게 도움이된다고 생각한다. 즉, 두 가지 이유로 인해 스크립트가 작동하지 않습니다. 1) 내 GNU LS가 오래되어 'ls -lh'(K / M / G / T가 아닌 바이트) 및 2)에 대해 사람이 읽을 수있는 다른 크기 출력을 제공합니다. 버킷이 너무 많습니다. 1K와 1G 사이의 파일 크기에는 2000 개의 버킷이 있으며 그 중 절반은 1KB이고 그 중 절반은 1MB입니다. 나에게 새로운 'uniq -c'의 경우 가치가 있습니다.
notpeter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.