ডিরেক্টরি শাখার মধ্যে নির্দিষ্ট ফাইলের মোট আকার সন্ধান করুন


140

ধরুন একটি চিত্র স্টোরেজ ডিরেক্টরি আছে, বলুন, ./photos/john_doeযার মধ্যে একাধিক উপ-ডিরেক্টরি রয়েছে, যেখানে অনেকগুলি নির্দিষ্ট ফাইল থাকে (বলে, *.jpg) say আমি কীভাবে john_doeশাখার নীচে সেই ফাইলগুলির সংক্ষিপ্ত আকার গণনা করতে পারি ?

আমি চেষ্টা করেছি du -hs ./photos/john_doe/*/*.jpg, তবে এটি কেবল স্বতন্ত্র ফাইলগুলি দেখায়। এছাড়াও, এই ডিরেক্টরিটি কেবল প্রথম নীড় স্তরের অবস্থানটিকে john_doeপছন্দ করে john_doe/june/তবে এড়িয়ে যায় john_doe/june/outrageous/

সুতরাং, আমি কীভাবে নির্দিষ্ট ফাইলগুলির আকারের সংমিশ্রণ করে পুরো শাখাটি অতিক্রম করব?

উত্তর:


183
find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$

যদি duফাইল তালিকাগুলি খুব দীর্ঘ হয় বলে একাধিক প্রার্থনার প্রয়োজন হয় তবে একাধিক যোগফল প্রতিবেদন করা হবে এবং সংক্ষিপ্তকরণের প্রয়োজন হবে।


7
Find -iname 'file *' -exec du -cb {} + | গ্রেপ মোট $ | কাট -ফ 1 | পেস্ট-এসডি + - | বিসি # সংখ্যক বাইট আকার
মিশাল আইজমজিয়া

3
যদি আপনার সিস্টেমটি অন্য ভাষার অধীনে কাজ করে তবে আপনার পোলিশ ভাষায় মোট ra রাজেম like এর মতো অন্য শব্দে পরিবর্তন করতে হবে।
জবিস্কেক

1
আপনি LC_ALL=POSIXসর্বদা এর জন্য মোটের জন্য গ্রেপ হিসাবে উপসর্গ হিসাবে যুক্ত করতে পারেন :LC_ALL=POSIX find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
সোভেন

2
যদি আপনি ব্যবহার না করে থাকেন -nameতবে গ্রেপ পরিবর্তন করুন grep -P "\ttotal$"অথবা অন্যথায় এটি "মোট" দিয়ে শেষ হওয়া সমস্ত ফাইল ক্যাপচার করবে।
thdoan

3
@ মাইকেলালিজমজিয়া কয়েকটি শেল (যেমন উইন্ডোজের জন্য গিট ব্যাশ) আসে না bc, সুতরাং এখানে আরও বহনযোগ্য সমাধান দেওয়া হয়েছে:find -name '*.jpg' -type f -exec du -bc {} + | grep total$ | cut -f1 | awk '{ total += $1 }; END { print total }'
30:57

50
du -ch public_html/images/*.jpg | grep total
20M total

.jpgএই ডিরেক্টরিতে আমার ফাইলগুলির মোট ব্যবহার আমাকে দেয় ।

একাধিক ডিরেক্টরি ডিল করার জন্য আপনাকে সম্ভবত এটি findকোনওভাবে একত্রিত করতে হবে ।

আপনি du কমান্ডের উদাহরণগুলি দরকারী খুঁজে পেতে পারেন (এটিতে অন্তর্ভুক্ত রয়েছে find)


2
এটি অন্তর্নিহিত ডিরেক্টরিগুলি অতিক্রম করে না?
mbaitoff

এটি গৃহীত সমাধানের চেয়ে টাইপ করা সহজ, তবে এটি কেবল অর্ধ-ডান, এটি উপ-ডিরেক্টরিতে চিত্রগুলি অন্তর্ভুক্ত করবে না। সমস্ত ফাইল একটি ডিরেক্টরিতে রয়েছে কিনা তা জানা ভাল।
gbmhunter

@gbmhunter আমি মনে করি আপনি যদি -আর -আর প্যারামিটার যুক্ত করেন তবে আপনি সাব-ডাইরেক্টরিগুলিও পাবেন কারণ এটি ডিরেক্টরি গাছটিকে পুনরাবৃত্তভাবে অনুসরণ করে। নিশ্চিত করার পরেও চেষ্টা করার জন্য আমি বর্তমানে কম্পিউটারে নেই।
লেভন

1
Man7.org/linux/man-pages/man1/du.1.html-R এ আমি কোনও বিকল্প দেখতে পাচ্ছি না । এবং আমি মনে করি না যে কোনও পুনরাবৃত্তির বিকল্পটি এই ক্ষেত্রে সহায়তা করবে কারণ শেলটি আর্গুমেন্টগুলি পাস করার আগে গ্লোব সম্প্রসারণ করছে । du
gbmhunter

22

প্রাথমিকভাবে, আপনার দুটি জিনিস প্রয়োজন:

du -ch -- **/*.jpg | tail -n 1

খুব ভাল উত্তর। সন্ধানের ব্যবহারের চেয়ে সহজ (যতক্ষণ না * বা ** ডিরেক্টরি কাঠামোর সাথে মেলে)
আন্দ্রে দে মিরান্ডা

এটি ফাইলগুলির খুব দীর্ঘ তালিকাগুলি পরিচালনা করতে পারে যেখানে ব্যবহার করে findভুল ফলাফল পাওয়া যায়।
এরিক ফর্নি

বাশ ব্রেস সম্প্রসারণ ওয়াইল্ডকার্ডের একাধিক সেটও পরিমাপ করার অনুমতি দেয়। du -ch -- ./{dir1,dir2}/*.jpgবাdu -ch -- ./{prefix1*,prefix2*}.jpg
জে.মনি

@ এরিকফৌনি যাইহোক Argument list too longপ্রায় 300k পাঠ্য ফাইল প্রসেস করার সময় আমি ত্রুটি পেয়েছি ।
xtluo

কোনও কমান্ডের জন্য সর্বাধিক সংখ্যক আর্গুমেন্ট (এই ক্ষেত্রে, ওয়াইল্ডকার্ড সম্প্রসারণের মাধ্যমে ফাইলের নামগুলি ফিরিয়ে দেওয়া) চেক করা যায় getconf ARG_MAX। আপনার যদি আরও থাকে তবে আপনার এক থেকে এক বা ব্যাচের দিকে লুপের জন্য ফাইলগুলি প্রক্রিয়া করতে হবে।
এরিক ফর্নি

17

চূড়ান্ত উত্তর:

{ find <DIR> -type f -name "*.<EXT>" -printf "%s+"; echo 0; } | bc

এবং আরও দ্রুত সংস্করণ, র‌্যাম দ্বারা সীমাবদ্ধ নয়, তবে এর জন্য বিগনাম সমর্থন সহ জিএনইউ অ্যাডব্লিউকে দরকার:

find <DIR> -type f -name "*.<EXT>" -printf "%s\n" | gawk -M '{t+=$1}END{print t}'

এই সংস্করণে নিম্নলিখিত বৈশিষ্ট্য রয়েছে:

  • findআপনার সন্ধান করা ফাইলগুলি নির্দিষ্ট করার জন্য সমস্ত ক্ষমতা capabilities
  • লক্ষ লক্ষ ফাইল সমর্থন করে
    • এখানে অন্যান্য উত্তরগুলি যুক্তি তালিকার সর্বাধিক দৈর্ঘ্যের দ্বারা সীমাবদ্ধ
  • একটি ন্যূনতম পাইপ থ্রুপুট দিয়ে কেবল 3 টি সহজ প্রক্রিয়া তৈরি করে
    • এখানে অনেক উত্তর সি + এন প্রক্রিয়াগুলি স্পেন করে, যেখানে সি কিছু ধ্রুবক এবং এন ফাইলগুলির সংখ্যা
  • স্ট্রিং ম্যানিপুলেশন নিয়ে বিরক্ত করবেন না
    • এই সংস্করণটি কোনও গ্রেপিং, বা রেজেক্সিং করে না
    • ভাল, findফাইলের সাথে একটি সাধারণ ওয়াইল্ডকার্ড মিলছে
  • ঐচ্ছিকভাবে একটি পাঠযোগ্য ফর্ম মধ্যে সমষ্টি ফরম্যাট (যেমন। 5.5K, 176.7M, ...)
    • যে সংযোজন করতে | numfmt --to=si

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

1
প্রতিক্রিয়াটির জন্য @ অ্যান্ডব ধন্যবাদ, ধনুর্বন্ধকের আশেপাশের ফাঁকা স্থানগুলি অবশ্যই বেসে প্রয়োজন, আমি জেডএসএইচ ব্যবহার করছি যাতে আমি এটি লক্ষ্য করি না। বিসি-র মেমরির ব্যবহার ধীরে ধীরে বৃদ্ধি পাওয়ার সাথে সাথে আপনার সিস্টেমে উপলব্ধ র‌্যামের মাধ্যমে ফাইলের সংখ্যা সীমাবদ্ধ রয়েছে
জান চেন - রাইন্ডেল

8

এখনও অবধি দেওয়া উত্তরগুলিতে আমলে নেওয়া হয় না যে ফাইন্ড লিস্ট থেকে ডুতে পাস করা ফাইল তালিকাটি এত দীর্ঘ হতে পারে যা স্বয়ংক্রিয়ভাবে তালিকাটিকে খণ্ডগুলিতে বিভক্ত করে, যার ফলে একাধিক ঘটনা ঘটে total

আপনি হয় grep total(লোকাল!) এবং ম্যানুয়ালি যোগ করতে পারেন, বা আলাদা কমান্ড ব্যবহার করতে পারেন। এএফআইকে সমস্ত ফাইলের গ্র্যান্ড টোটাল (কিলোবাইটে) পাওয়ার দুটি উপায় রয়েছে যা খুঁজে পেয়েছেন:
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'

ব্যাখ্যা
find . -type f -iname '*.jpg' -print0: কেস (যেমন * .jpg, * .JPG, * .Jpg ...) নির্বিশেষে এক্সটেনশন jpg সহ সমস্ত ফাইল সন্ধান করুন এবং সেগুলি আউটপুট করুন (নাল-টার্মিনেটেড)।
xargs -r0 du -a: -আর: জার্গস কোনও আর্গুমেন্ট পাস না করেও কমান্ডটি কল করবে যা -r বাধা দেয়। -0 এর অর্থ নাল-টার্মিনেটেড স্ট্রিং (নিউলাইন টার্মিনেটেড নয়)।
awk '{sum+=$1} END {print sum}': পূর্ববর্তী কমান্ড দ্বারা ফাইলের আকারের আউটপুট যোগ করুন

এবং রেফারেন্সের জন্য, অন্য উপায় হবে
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-


অতিরিক্ত ইঙ্গিত: আমার এইচডিডি তে 23428 টি ফাইল (22323 চিত্র হচ্ছে) প্রথম পদ্ধতিটি 1 সেকেন্ড এবং দ্বিতীয়টি 3.8 সেকেন্ডে চালায়।
জানুয়ারী

লক্ষ্য করুন যে উভয়ই একটি জিএনইউ সিস্টেম ধরে নিয়েছে। প্রথমটি ধরে নেওয়া হয় যে ফাইলের নামগুলিতে নতুন লাইনের অক্ষর নেই।
স্টাফেন চেজেলাস

আমি বাজি du --file0-fromধরব কারণ আপনি এটি প্রথম চালিয়েছেন (ক্যাচিং এফেক্ট)।
স্টাফেন চেজেলাস

এর সাথে xargsবেশ কয়েকটি du -aচালিত হতে পারে, তাই যদি শক্ত লিঙ্ক থাকে তবে আপনার মধ্যে তাত্পর্য থাকতে পারে।
স্টাফেন চেজেলাস

3

যদি ফাইলগুলির তালিকাটি খুব বড় হয় তবে এটি du -cকোনও জিএনইউ সিস্টেমে একক অনুরোধে পাস করা যায় না , আপনি এটি করতে পারেন:

find . -iname '*.jpg' -type f -printf '%b\t%D:%i\n' |
  sort -u | cut -f1 | paste -sd+ - | bc

(আকার 512 বাইট ব্লকের সংখ্যায় প্রকাশিত)। ভালো লেগেছে duএটা শুধুমাত্র একবার হার্ড সংযোগগুলি গণনা করার চেষ্টা করে। আপনি যদি হার্ডলিঙ্কগুলির বিষয়ে চিন্তা না করেন তবে আপনি এটিকে সহজ করতে পারেন:

(printf 0; find . -iname '*.jpg' -type f -printf +%b) | bc

আপনি যদি ডিস্ক ব্যবহারের পরিবর্তে আকারটি চান তবে এর %bসাথে প্রতিস্থাপন করুন %s। আকারটি তখন বাইটে প্রকাশ করা হবে।


-bash: bc: command not foundসেন্টোস - লিনাক্স 2.6.32-431.el6.x86_64
ইয়েয়া

@yeya, আপনার CentOS মোতায়েনটি ভেঙে গেছে বলে মনে হচ্ছে। bcএকটি অ-nonচ্ছিক POSIX কমান্ড।
স্টাফেন চেজেলাস

1

এখনও অবধি উল্লিখিত সমাধানগুলি অদক্ষ (এক্সিকিউটি ব্যয়বহুল) এবং ফাইল তালিকাটি দীর্ঘ হয় বা তারা ম্যাক ওএস এক্সে কাজ না করে তবে অতিরিক্ত ম্যানুয়াল কাজের প্রয়োজন যোগ করতে পারে following নিম্নলিখিত সমাধানটি খুব দ্রুত, কোনও সিস্টেমে কাজ করা উচিত, এবং জিবিতে মোট উত্তর দেয় (মোট এমবিতে দেখতে চাইলে একটি / 1024 সরিয়ে ফেলুন): find . -iname "*.jpg" -ls |perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'


আমরাও -inameনা -lsমান / পোর্টেবল হয়, তাই এটি করা হবে না কোনো সিস্টেমে কাজ পারেন। ফাইললাইনম বা সিমলিংক লক্ষ্যগুলি রয়েছে যাতে নতুন লাইনের অক্ষর রয়েছে সেগুলি এটি সঠিকভাবে কাজ করবে না।
স্টাফেন চেজেলাস

এছাড়াও নোট করুন যে এটি ফাইলের আকারগুলির যোগফল দেয়, তাদের ডিস্ক ব্যবহার না করে। সিমলিঙ্কগুলির জন্য, এটি সিমলিংকের আকার দেয়, তারা যে ফাইলগুলি দেখায় not
স্টাফেন চেজেলাস

1

কোনও স্থানীয় লোকের সাথে এটি কাজ করার জন্য এসএইচডাব্লু এর দুর্দান্ত উত্তরের উন্নতি করা, যেমন জবিস্কেক ইতিমধ্যে তার মন্তব্যে উল্লেখ করেছেন:

LC_ALL=C find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$

1

ডু স্বাভাবিকভাবে ডিরেক্টরি শ্রেণিবিন্যাসকে চিহ্নিত করে এবং অ্যাডাব্লিকেশন ফিল্টারিং সম্পাদন করতে পারে যাতে এর মতো কিছু যথেষ্ট হতে পারে:

du -ak | awk 'BEGIN {sum=0} /\.jpg$/ {sum+=$1} END {print sum}'

এটি জিএনইউ ছাড়াই কাজ করে।


1
এটি আরও ব্যয়বহুল যেহেতু এটি statএমন ফাইলগুলির জন্য কল দেয় যা সন্ধানের ধরণটির সাথে মিল রাখে না।
Law29

কেবলমাত্র এই সমাধানটি আমার ম্যাকের জন্য কাজ করে।
ম্যাথিয়াস এম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.