2009-05-22 15 views
100

कौन सा एक बहुत बड़ी फाइलों पर अधिक कुशल है और इसका उपयोग किया जाना चाहिए?find -exec cmd {} + बनाम | xargs

find . -exec cmd {} + 

या

find . | xargs cmd 

(मान लें वहाँ फ़ाइल नाम में कोई अजीब चरित्र है कि)

+0

संबंधित: https://stackoverflow.com/questions/9612090/how-to-loop-through-file-names-returned-by-find –

उत्तर

94

find . -print0 | xargs -0 cmd 

इस भले ही फ़ाइल नाम फंकी वर्ण हो काम करेंगे (-print0find प्रिंट NUL-समाप्त मैचों बना देता है, -0xargs इस प्रारूप की उम्मीद करता है।):

निम्नलिखित में इस्तेमाल किया जा करने का सुझाव दिया है गति अंतर महत्वहीन होगा।

लेकिन आप यह सुनिश्चित करना है कि:

  1. आपकी स्क्रिप्ट मान नहीं होगा कि कोई फ़ाइल अंतरिक्ष, टैब, फ़ाइल के नाम में आदि होगा; पहला संस्करण सुरक्षित है, दूसरा नहीं है।

  2. आपकी स्क्रिप्ट एक विकल्प के रूप में "-" से शुरू होने वाली फ़ाइल का इलाज नहीं करेगी।

तो अपने कोड इस तरह दिखना चाहिए:

find . -exec cmd -option1 -option2 -- {} + 

या

find . -print0 | xargs -0 cmd -option1 -option2 -- 

पहले संस्करण छोटा और आसान है के रूप में आप 1 अनदेखा कर सकते हैं लिखने के लिए, लेकिन दूसरा संस्करण अधिक पोर्टेबल और सुरक्षित है, क्योंकि "-exec cmd {} +" जीएनयू निष्कर्षों में अपेक्षाकृत नया विकल्प है (2005 से, बहुत से चलने वाले सिस्टमों में अभी तक यह नहीं होगा) और यहथा। इसके अलावा बहुत से लोग इस "-exec cmd {} +" को नहीं जानते हैं, जैसा कि आप अन्य उत्तरों से देख सकते हैं।

+4

-print0 भी एक जीएनयू ढूंढ (और जीएनयू xargs) विकल्प है जो गायब है बहुत से गैर-लिनक्स सिस्टम से, इसलिए पोर्टेबिलिटी तर्क मान्य नहीं है।केवल -प्रिंट का उपयोग करना और xargs के -0 को छोड़ना, हालांकि, * बहुत पोर्टेबल है। – dannysauer

+4

बिंदु यह है कि बिना किसी प्रिंटर 0, यदि कोई स्थान या टैब आदि वाली कोई फ़ाइल है तो यह काम नहीं करता है। यह एक सुरक्षा भेद्यता हो सकती है जैसे कि "foo -o index.html" जैसे फ़ाइल नाम है- तो एक विकल्प के रूप में इलाज किया। खाली निर्देशिका में आज़माएं: "स्पर्श करें - foo \ -o \ index.html; ढूंढें। | Xargs cat"। आपको मिल जाएगा: "बिल्ली: अमान्य विकल्प - 'ओ'" – Tometzky

+2

उनका उदाहरण एक फ़ाइल नाम है जिसमें एक - है। बिना प्रिंट 0, खोज थूक जाएगा ./foo -o index.html। तो शायद एक के साथ शुरू करना - एक बड़ा सौदा नहीं है, लेकिन नतीजा थोड़ा बदल गया है, और एक बहुउद्देश्यीय प्रणाली पर, यदि आपकी स्क्रिप्ट विश्व पठनीय है तो हमलावर वेक्टर प्रदान कर सकता है। – bobpaul

7
find . | xargs cmd 

अधिक कुशल है (यह cmd संभव के रूप में कई बार के रूप में चलाता है, exec के विपरीत, जो प्रत्येक मैच के लिए cmd चलाता है)। हालांकि, अगर फ़ाइल नामों में रिक्त स्थान या फंकी वर्ण होते हैं तो आप परेशानी में भाग लेंगे।

+25

यह नहीं "लगता है -exec cmd {} \।," है लेकिन "ढूंढें। -exec cmd {} +"। उत्तरार्द्ध एक समय में एक फाइल नहीं चलाएगा। – Tometzky

+2

ध्यान दें कि 'xargs' दृष्टिकोण वास्तव में धीमा है यदि कोई (या केवल कुछ) मिलान करने वाली फ़ाइलें नहीं हैं और' cmd' में प्रत्येक फ़ाइल के लिए बहुत कुछ नहीं है। उदाहरण के लिए, जब खाली निर्देशिका में चलाया जाता है, तो 'xargs' संस्करण कम से कम दो बार ले जाएगा, क्योंकि केवल दो की बजाय दो प्रक्रियाएं शुरू की जानी चाहिए। (हां, अंतर आमतौर पर * निक्स पर अचूक है, लेकिन एक लूप में यह महत्वपूर्ण हो सकता है; या, इसे विंडोज़ पर कुछ समय आज़माएं ...) – SamB

संबंधित मुद्दे