কমান্ড প্রম্পট থেকে ফাইল আকারের বিতরণ তৈরি করুন


16

আমি একটি ফাইল সিস্টেম পেয়েছি যার কয়েক মিলিয়ন ফাইল রয়েছে এবং আমি একটি নির্দিষ্ট ডিরেক্টরিতে পুনরাবৃত্তভাবে ফাইলের আকারগুলির একটি বিতরণ দেখতে চাই। আমি মনে করি এটি কিছু ব্যাশ / অ্যাজক ফু দিয়ে সম্পূর্ণভাবে করণীয় তবে একটি হাত ব্যবহার করতে পারে। মূলত আমি নিম্নলিখিত মত কিছু চাই:

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

আমি মনে করি এটি একটি লুপ এবং কিছু শর্তাধীন লগ 2 ফাইলাইজ ফু দেওয়া খুব খারাপ হওয়া উচিত নয়, তবে আমি সেখানে পৌঁছানোর মতো দেখতে পাচ্ছি না।

সম্পর্কিত প্রশ্ন: এক্স বাইটের চেয়ে বড় / ছোট ফাইলগুলি কীভাবে খুঁজে পাব?

উত্তর:


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 এর পরিবর্তে আপনার উত্তরটি ব্যবহারের জন্য সম্পাদনা করেছি যাতে এটি পুনরাবৃত্ত হয় এবং কোনও ডিরেক্টরি গণনা না করে। বাম হাতের কলাম আউটপুটটি সুন্দর করার জন্য যে কেউ ক্র্যাক করতে চায়?
notpeter

কিন্তু মূল প্রশ্ন "একটি নির্দিষ্ট ডিরেক্টরির মধ্যে ফাইলের মাপ বিতরণের" সম্পর্কে ছিল, তাই এটি পরিবর্তন করতে ঠিক হবে না lsএকটি থেকে find। আমি এটি আগের মতো করে রাখছি।
গ্যারিজোহান

@ নোটপেটার: দুঃখিত, আমি আপনাকে প্রশ্নের লেখক হিসাবে চিনতে পারি নি। আমি আমার উত্তর পরিবর্তন করেছি এটি পুনরাবৃত্তভাবে অনুসন্ধান করতে। আমার সিস্টেমে, যদিও ব্যবহার xargsকরা তুলনায় উল্লেখযোগ্যভাবে দ্রুত -exec, তাই আমি সেই পদ্ধতিটি ব্যবহার করেছি।
গ্যারিজোহান

1
কোন চিন্তা করো না. এখন আমরা আমাদের মন্তব্যগুলি মুছে ফেলতে পারি ভান করা হয় এটি সর্বদা সঠিক উত্তর ছিল। ;)
notpeter

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-kib-mib-etc -একটি-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]থাকে তবে ফাইলের আকারটি <1K। যেহেতু আমি কল্পনা করছি যে আপনি এই জাতীয় ছোট আকারের বিষয়ে চিন্তা করেন না, তাই স্ক্রিপ্টটি 1Kসমস্ত ফাইলের জন্য মুদ্রণ করবে যার আকার <= 1K is

  • else{printf "%.0f%s\n",k[1],k[2]} : যদি ফাইলটি 1K এর চেয়ে বড় হয় তবে ফাইলের আকারটি নিকটতম পূর্ণসংখ্যার সাথে গোল করে এবং এর সংশোধক (কে, এম, বা জি) সহ প্রিন্ট করুন।

  • sort | uniq -c : মুদ্রিত প্রতিটি লাইন (ফাইলের আকার) এর উপস্থিতি গণনা করুন।

  • sort -hk 2: মানব পাঠযোগ্য বিন্যাসে দ্বিতীয় ক্ষেত্র অনুসারে বাছাই করুন। এইভাবে, 7Gপরে বাছাই করা হয় 8M


আমি ব্যাখ্যার প্রশংসা করি, আমি মনে করি যে এটি লোকেরা এটির চেষ্টা করার জন্য এটি সহায়ক। এটি বলেছিল, আপনার স্ক্রিপ্টটি দুটি কারণে আমার জন্য কাজ করে না 1) আমার জিএনইউ এলএস পুরানো এবং তাই 'ls -lh' (কে / এম / জি / টি নয় বাইটস) এবং 2) এর জন্য বিভিন্ন মানব পাঠযোগ্য আকারের আউটপুট দেয় কারণ অনেকগুলি বালতি আছে 1K এবং 1G এর মধ্যে ফাইল আকারের সাথে 2000 বালতি রয়েছে যার অর্ধেক 1KB অর্ধেক যা 1MB। যদিও এটি 'ইউনিট-সি' এর জন্য আমার পক্ষে নতুন new
notpeter
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.