find -exec + बनाम खोजें | xargs: कौन सा चुनना है?


32

मैं समझता हूं कि इसके व्यवहार की नकल करने का विकल्प -execलिया जा सकता +है xargs। क्या कोई स्थिति है जहाँ आप एक रूप को दूसरे पर पसंद करेंगे?

मैं व्यक्तिगत रूप से पहले रूप को पसंद करता हूं, यदि केवल एक पाइप का उपयोग करने से बचने के लिए। मुझे findयकीन है कि डेवलपर्स ने उचित अनुकूलन किया होगा। क्या मैं सही हूँ?

जवाबों:


21

आप शायद कॉल करना चाहते हैं (एक बार, जब आपने सीखा, कि यह संभव है, जो आज हो सकता है)। यह, ज़ाहिर है, केवल तब तक संभव है जब तक आप पाते हैं। एक बार जब आप xargs पर जाते हैं तो यह कार्यक्षेत्र से बाहर हो जाता है।

छोटा उदाहरण, दो फाइलें a.lst और b.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

यहां कोई ट्रिक नहीं है - बस यह तथ्य कि दोनों में "फडेल" है, लेकिन केवल एक "फिडेल" शामिल है।

हमें लगता है कि पता नहीं था। हम ऐसी फ़ाइल खोजते हैं जो 2 स्थितियों से मेल खाती हो:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

ठीक है, शायद आप दोनों स्ट्रिंग्स को शर्त के रूप में पारित करने के लिए grep या किसी अन्य प्रोग्राम के लिए सिंटैक्स जानते हैं, लेकिन यह बात नहीं है। प्रत्येक प्रोग्राम जो सही या गलत वापस आ सकता है, एक फाइल को तर्क के रूप में दिया जा सकता है, यहां इस्तेमाल किया जा सकता है - grep सिर्फ एक लोकप्रिय उदाहरण था।

और ध्यान दें, आप का अनुसरण कर सकते -exec लगता है , अन्य खोज आदेशों के साथ की तरह -LS या -delete या कुछ इसी तरह। ध्यान दें, कि डिलीट न केवल rm (फाइल्स को रिमूव करता है) करता है, बल्कि rmdir (डायरेक्ट्रीज को भी हटाता है)।

इस तरह की श्रृंखला को AND के आदेशों के संयोजन के रूप में पढ़ा जाता है, जब तक कि अन्यथा निर्दिष्ट न किया जाए (अर्थात एक -orस्विच के साथ (और parens (जिसे मास्किंग की आवश्यकता होती है))।

तो आप खोज श्रृंखला नहीं छोड़ रहे हैं, जो एक आसान बात है। -Xargs का उपयोग करने में मुझे कोई फायदा नहीं दिखता है, क्योंकि आपको फाइलों को पास करने में सावधानी बरतनी होती है, जो कुछ ऐसा है जिसे करने की आवश्यकता नहीं है - यह स्वचालित रूप से प्रत्येक फ़ाइल को आपके लिए एकल तर्क के रूप में पारित करता है।

यदि आपको लगता है कि आपको {} ब्रेसिज़ के लिए कुछ मास्किंग की आवश्यकता है , तो मेरे प्रश्न पर जाने के लिए स्वतंत्र महसूस करें जो प्रमाण मांगता है। मेरा दावा है: आप नहीं


3
इस पोस्ट ने मेरी आँखों को प्रयोग के एक नए तरीके से खोल दिया है find। आपका बहुत बहुत धन्यवाद!
रहमू

1
"-Xargs का उपयोग करने में मुझे कोई फायदा नहीं दिख रहा है"। क्या है -execऐसा करने का तरीका xargs -P4तो यह है कि चार कोर के तीन बेकार नहीं रहते?
डेमियन येरिक

1
@DamianYerrick: अंतिम -exec कमांड "में नहीं;" लेकिन एक + (/ प्लस चिह्न) के साथ।
उपयोगकर्ता अज्ञात

25

सुरक्षित रूप से पाइपिंग फ़ाइल नाम की xargsआवश्यकता है कि आपके विकल्प findका समर्थन करता -print0है और आपके xargsपास इसे ( --nullया -0) पढ़ने के लिए संबंधित विकल्प है । अन्यथा, अनुचित वर्ण या बैकस्लैश या उद्धरण या नाम में व्हाट्सएप के साथ फ़ाइल नाम अप्रत्याशित व्यवहार का कारण बन सकता है। दूसरी ओर, find -exec {} +में है POSIX findकल्पना , तो यह पोर्टेबल है, और यह रूप में सुरक्षित के रूप में के बारे में है find -print0 | xargs -0, और निश्चित रूप से अधिक सुरक्षित find | xargs। मैं बिना कभी नहीं करने की सलाह दूंगाfind | xargs-print0


6
find … -exec … {} +OpenBSD की पोर्टेबिलिटी के लिए एक उल्लेखनीय अपवाद है, जिसने केवल 2012 में जारी संस्करण 5.1 के साथ इस सुविधा का अधिग्रहण किया था। सभी BSD को -print0कई वर्षों के लिए, यहां तक ​​कि OpenBSD (हालांकि यह थोड़ी देर के लिए भी उस सुविधा का विरोध किया था) का अधिग्रहण किया । दूसरी ओर, सोलारिस, POSIX सुविधाओं से चिपक जाता है, इसलिए आप प्राप्त करते हैं -exec +और नहीं -print0
गाइल्स का SO- बुराई पर रोक '23

-print0एक दर्द है और यद्यपि आप तर्क कर सकते हैं xargs --delimiter "\n"कि यह समतुल्य नहीं है, मैंने कभी भी बाद की खोज के बाद पूर्व का उपयोग नहीं किया है।
श्रीधर सरनोबत

3
मैं यह नहीं देखता कि -0दर्द किस तरह से ज्यादा है --delimiter "\n"
jw013

2
अगर कोई इनपुट नहीं है -0, तो इसके अलावा , GNU को कमांड चलाने से बचने की xargsआवश्यकता -rहै।
स्टीफन चेज़लस

2
एक और समस्या | xargs -r0 cmdयह है कि cmdxargs/dev/null
स्टड

10

यदि आप -exec ... ;प्रपत्र (अर्धविराम से बचने के लिए याद रखना) का उपयोग करते हैं, तो आप फ़ाइल नाम के अनुसार एक बार कमांड चला रहे हैं। यदि आप उपयोग करते हैं -print0 | xargs -0, तो आप फ़ाइल नाम के अनुसार कई कमांड चलाते हैं। आपको निश्चित रूप से -exec +फॉर्म का उपयोग करना चाहिए , जो एक ही कमांड लाइन में कई फाइलें डालता है और बड़ी संख्या में फाइलों के शामिल होने पर बहुत तेज होता है।

उपयोग xargsकरने का एक बड़ा प्लस समानांतर उपयोग में कई कमांड चलाने की क्षमता है xargs -P। मल्टी-कोर सिस्टम पर, जो भारी समय की बचत प्रदान कर सकता है।


6
आप के -Pबजाय मतलब था -p। ध्यान रखें xargs -Pकि POSIX मानक में नहीं है, जबकि find -exec {} +पोर्टेबिलिटी के लिए जा रहा है, तो यह महत्वपूर्ण है।
jw013

@ एलेक्सियो आपको प्लस साइन से बचने की ज़रूरत नहीं है, क्योंकि शेल के लिए इसका कोई विशेष अर्थ नहीं है: find /tmp/ -exec ls "{}" +ठीक काम करता है।
डैनियल कुलमन

1
कोर्स, निश्चित रूप से। मैं -execइतने लंबे समय के बाद सब कुछ से बच रहा हूं (मैं एक मर्दवादी हूं, मैं बचने के लिए उद्धरणों का उपयोग नहीं करता {}, मैं हमेशा टाइप करता हूं \{\}; पूछें नहीं), सबकुछ ऐसा लगता है कि अब बच जाना चाहिए।
Alexios

1
@ एलेक्सियो: यदि आपको एक उदाहरण मिलता है (एक मसोकिस्ट होने के अलावा) जहां ब्रेसिज़ की मास्किंग उपयोगी है, तो कृपया इसे मेरे प्रश्न के उत्तर के रूप में प्रदान करें - यह संकेत पुराना है और केवल मैनपेज में एक राहत है। मैंने कभी ऐसा उदाहरण नहीं देखा, जहां find /tmp/ -exec ls {} +काम नहीं होगा।
उपयोगकर्ता अज्ञात

1
मेरे लिए, यह SunOS 4 के दिनों में बनाई गई मांसपेशियों की स्मृति है। जब से मैं इसे सालों से कर रहा हूं, मैं bashब्रेसिज़ शब्दशः स्वीकार करना शुरू करने में पूरी तरह से विफल रहा । मुझे पूरा यकीन है कि कम से कम एक पुराने गोले का उपयोग मैंने फेंक दिया है यदि ब्रेसिज़ बच नहीं गए हैं।
एलेक्सिओस

8

प्रदर्शन के बारे में मैंने सोचा कि -exec … +यह बेहतर होगा क्योंकि यह एक एकल उपकरण है जो सभी काम कर रहा है, लेकिन जीएनयू खोजुटिल के प्रलेखन का एक हिस्सा कहता है कि -exec … +कुछ मामलों में कम कुशल हो सकता है:

[के साथ मिल -exec … +] के कुछ उपयोगों की तुलना में कम कुशल हो सकता है xargs; उदाहरण के लिए xargsनई कमांड लाइनों को बनाने की अनुमति देता है जबकि पिछली कमांड अभी भी निष्पादित कर रही है, और आपको समानांतर में चलने के लिए कई कमांड निर्दिष्ट करने की अनुमति देती है। हालांकि, find ... -exec ... +निर्माण में व्यापक पोर्टेबिलिटी का लाभ है। GNU खोज ने -exec ... +4.2.12 [जनवरी 2005] संस्करण तक ' ' का समर्थन नहीं किया ; इसका एक कारण यह है कि इसमें -print0किसी भी मामले में पहले से ही ' ' कार्रवाई थी।

मुझे इस बात पर बिल्कुल यकीन नहीं था कि इसका क्या मतलब है, इसलिए मैंने उस चैट में पूछा जहां derobert ने इसे समझाया:

findसंभवतया -exec … +चल रहा है, जबकि फ़ाइलों के अगले बैच के लिए खोज जारी रख सकते हैं , लेकिन यह नहीं है।
find … | xargs …करता है, क्योंकि तब खोज एक अलग प्रक्रिया है, और यह तब तक चलता रहता है जब तक पाइप बफर भर नहीं जाता

(मेरे द्वारा प्रारूपण।)

तो वहाँ वह है। लेकिन अगर प्रदर्शन वास्तव में मायने रखता है तो आपको यथार्थवादी बेंचमार्किंग करनी होगी या यहाँ तक कि खुद से भी पूछना होगा कि क्या आप ऐसे मामलों के लिए शेल का उपयोग करना चाहते हैं।

यहाँ इस साइट पर मुझे लगता है कि लोगों को -exec … +जब भी संभव हो फॉर्म का उपयोग करने की सलाह देना बेहतर होता है क्योंकि यह सरल है और यहां अन्य उत्तरों में वर्णित कारणों के लिए (जैसे कि बहुत सोचने के बिना अजीब फ़ाइलनामों को संभालना)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.