कमांड प्रॉम्प्ट से फ़ाइल आकार का वितरण उत्पन्न करें


16

मुझे एक फाइलसिस्टम मिला है जिसमें कुछ मिलियन फाइलें हैं और मैं एक विशेष निर्देशिका में फ़ाइल आकार के वितरण को पुनरावृत्ति से देखना चाहूंगा। मुझे ऐसा लगता है कि यह कुछ बैश / अजीब फू के साथ पूरी तरह से उल्लेखनीय है, लेकिन एक हाथ का उपयोग कर सकता है। मूल रूप से मैं कुछ इस तरह का काम करना चाहूंगा:

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

मुझे लगता है कि यह बहुत बुरा नहीं होना चाहिए एक पाश और कुछ सशर्त log2 फ़ाइल foo दिया, लेकिन मैं वहाँ पाने के लिए प्रतीत नहीं कर सकते।

संबंधित प्रश्न: मैं एक्स बाइट्स की तुलना में बड़ी / छोटी फाइलें कैसे पा सकता हूं?

जवाबों:


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 के बजाय खोजने का उपयोग करने के लिए संपादित किया ताकि यह पुनरावर्ती हो और किसी भी निर्देशिका की गिनती न करें। किसी को भी बाएं हाथ के स्तंभ उत्पादन सुंदर बनाने पर एक दरार लेना चाहते हैं?
नोटरी

लेकिन मूल प्रश्न "एक विशेष निर्देशिका में फ़ाइल आकार के वितरण" के बारे में था, इसलिए इसे lsए में बदलना ठीक नहीं है find। मैं इसे वापस उसी तरह से डाल रहा हूं जैसे यह था।
गैरीजोन

@ नोटरी: क्षमा करें, मैंने आपको प्रश्न के लेखक के रूप में नहीं पहचाना। मैंने इसे पुनः खोज करने के लिए अपना उत्तर बदल दिया। हालांकि, मेरे सिस्टम में, का उपयोग करने xargsकी तुलना में काफी तेज है -exec, इसलिए मैंने उस पद्धति का उपयोग किया।
गैरीजोन

1
कोई चिंता नहीं। अब हम केवल अपनी टिप्पणियों को हटा सकते हैं दिखावा कर रहे हैं कि यह हमेशा सही उत्तर था। ;)
नोटरी

14

गैरीजोन के जवाब के आधार पर, यहां एक-लाइनर है, जो मानव पठनीय के आउटपुट को भी प्रारूपित करता है:

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-bib-mib-etc तरह-du-ls1

नमूना आउटपुट जैसा दिखता है:

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

मैंने यह समाधान चुना ताकि यह पता लगाया जा सके कि ZFS पर OS इंस्टॉलेशन के रिकॉर्ड को सेट करने के लिए कौन सी फाइलें 128K और नीचे हैं। मुझे डर है कि यह 128 के रिकॉर्ड आकार की तुलना में कई फाइलों के छोटे होने से मंदी का सामना कर रहा है, लेकिन यह जानना मुश्किल है कि बिना फाइलों की गिनती के क्यों।
एवरीफ्रेमैन

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 

OUTPUT:

 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 {} \;: सरल पर्याप्त है, वर्तमान dir में फ़ाइलें ढूंढें और ls -lhउन पर चलाएँ

  • match($5,/([0-9.]+)([A-Z]+)/,k);: यह फ़ाइल का आकार निकालेगा, और प्रत्येक मिलान को सरणी में बचाएगा k

  • if(!k[2]){print "1K"}: यदि k[2]अपरिभाषित है तो फ़ाइल का आकार <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) मेरा जीएनयू एलएस पुराना है और इसलिए 'ls -lh' के लिए अलग-अलग मानव पठनीय आकार का आउटपुट देता है (बाइट्स नहीं के / एम / जी / टी) और 2) क्योंकि बहुत सी बाल्टियाँ हैं। 1K और 1G के बीच फ़ाइल आकार के साथ 2000 बाल्टियाँ हैं, जिनमें से आधे 1KB हैं जिनमें से 1MB हैं। हालांकि यह 'uniq -c' के लिए मेरे लिए नया है।
21 सितंबर को
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.