2009-08-24 27 views
7

मेरे पास निर्देशिकाओं का एक बड़ा सेट है जिसके लिए मैं कई सौ .txt फ़ाइलों के कुल आकार की गणना करने की कोशिश कर रहा हूं। मैंने यह कोशिश की, जो ज्यादातर काम करता है:"ढूंढें। -नाम * .txt | xargs du -hc" एकाधिक योग क्यों देता है?

find . -name *.txt | xargs du -hc 

लेकिन मुझे अंत में एक कुल देने की बजाय, मुझे कई मिलते हैं। मेरा अनुमान है कि पाइप एक समय में खोज के आउटपुट की इतनी सारी लाइनों पर ही गुजरती है, और डु प्रत्येक बस बैच पर चलती है। क्या इसके चारों ओर एक रास्ता है?

धन्यवाद! एलेक्स

+0

एचएम, ठीक है। मैंने कोशिश की: खोजें। -नाम * .txt | xargs -n 100000 du -hc लेकिन यह काम नहीं प्रतीत होता है - मुझे अधिक subtotals मिलता है, कम नहीं। खोजने का प्रयास कर रहा है। -नाम * .txt | xargs -L 1000 du -hc 'ठीक से काम नहीं करता है। या तो "xargs: तर्क सूची बहुत लंबी", या यह केवल बहुत कम फ़ाइलों पर चलती है। कोई अन्य विचार? धन्यवाद! एलेक्स –

उत्तर

11

कैसे उपयोग करने के बारे --files0-से विकल्प डु रहे हैं:

+0

मेरे लिए बहुत अच्छा काम करता है! –

+2

आह, यह मेरे लिए काम करता था, लेकिन मैंने निष्पादन इको सामान के बजाय -print0 का उपयोग किया। – tladuke

+0

हम्म ... मुझे -print0 विकल्प के बारे में पता नहीं था। वह _much_ क्लीनर है। धन्यवाद! – Sbodd

0

xargs उचित आकार के हिस्सों में अपना इनपुट बस्ट करता है - जो आप देख रहे हैं वह प्रत्येक भाग के लिए कुल योग है। इनपुट के हैंडलिंग को कॉन्फ़िगर करने के तरीकों पर xargs के लिए मैन पेज को देखें।

3

xargs प्रोग्राम यूनिक्स कमांड लाइन की अधिकतम लंबाई के कारण सीमाओं के लिए खातों को बैचों में तोड़ देता है। यह एक समय में अपने उप-संचार को चलाने से पहले भी अधिक कुशल है, लेकिन इनपुट की लंबी सूची के लिए, यह पर्याप्त समय कमांड चलाएगा कि प्रत्येक "रन" इतना छोटा है कि इससे समस्याएं नहीं आतीं।

इस वजह से, आपको प्रति "बैच" प्रति आउटपुट लाइन देखने की संभावना है कि xargs को चलाने की आवश्यकता है।

क्योंकि आप पा सकते हैं यह उपयोगी/दिलचस्प, आदमी पेज यहां ऑनलाइन पाया जा सकता: http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs


एक अन्य बात यह है कि नोट करने के लिए (और यह अपनी पोस्ट या मेरे गलतफहमी में कोई गलती हो सकता है) है कि आपके पास "* .txt" अनचाहे/उद्धृत है। यानी, आप

find . -name *.txt | xargs du -hc 

जहां आप शायद चाहते

find . -name \*.txt | xargs du -hc 

अंतर किया जा रहा है कि कमांड लाइन * फ़ाइल नामों की सूची में विस्तार किया जा सकता है कि मेल खाते हैं ... बल्कि * में गुजर से है ढूंढें, जो इसे एक पैटर्न के रूप में उपयोग करेगा।

find . -name "*.txt" -exec ls -lt {} \; | awk -F " " 'BEGIN { sum=0 } { sum+=$5 } END { print sum }' 
0

एक वैकल्पिक समाधान awk उपयोग करने के लिए है? आपको शून्य से समाप्त फ़ाइल आउटपुट उचित रूप से उत्पन्न करना होगा:

find . -name "*txt" -exec echo -n -e {}"\0" \; | du -hc --files0-from=- 

मेरे सिस्टम पर सही तरीके से काम करता है।

7
find . -print0 -iname '*.txt' | du --files0-from=- 

और यदि आप इसे के लिए खोज करने के लिए कई अलग अलग एक्सटेंशन करना चाहते करने के लिए सबसे अच्छा है:

find . -type f -print0 | grep -azZEi '\.(te?xt|rtf|docx?|wps)$' | du --files0-from=- 
+0

'-exec echo {} "= 0"; 'से याद रखना बहुत आसान है। इंतज़ार नही। यह सही नहीं है। उहह '-exec echo -n {} "\ 0" \; '। नहीं? '-exec echo $ # और @ * # (@! @ # $ @ # !!!' (बहुत बेहतर) – Stephen

+0

आपके द्वारा सूचीबद्ध पहला तरीका कभी भी '-इनम * .txt' परीक्षण और ग्लोब ' यदि आपके पास अपनी कार्यशील निर्देशिका में '.txt' फ़ाइलें हैं, तो 'find' निष्पादित होने से पहले .txt' का विस्तार होगा। – BroSlow

+0

आप सही हैं। टाइपो को इंगित करने के लिए धन्यवाद। मैंने इसे सही किया है। – OmnipotentEntity

3

एक और सरल उपाय:

find . -name *.txt -print0 | xargs -0 du -hc 
+1

आपकी गुणवत्ता में सुधार करने के लिए पोस्ट कृपया शामिल करें कि आपकी पोस्ट समस्या का समाधान कैसे करेगी/क्यों। –

0

एक वैकल्पिक समाधान बैश for उपयोग करने के लिए है लूप:

for i in `find . -name '*.txt'`; do du -hc $i | grep -v 'total'; done 

यह तब अच्छा है जब आपको लूप में क्या होता है इसके बारे में अधिक नियंत्रण की आवश्यकता होती है।