खोज: गायब तर्क


18

मैं निम्नलिखित कमांड चलाने की कोशिश कर रहा हूं:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +

यह एक त्रुटि लौटा रहा है:

find: missing argument to -exec

मैं नहीं देख सकता कि इस आदेश में क्या गलत है, क्योंकि यह मैन पेज से मेल खाता है:

-exec कमांड {} +

-Exec विकल्प का यह संस्करण चयनित फ़ाइलों पर निर्दिष्ट कमांड चलाता है, लेकिन अंत में प्रत्येक चयनित फ़ाइल नाम को जोड़कर कमांड लाइन का निर्माण किया जाता है; कमांड की कुल संख्या- tions कमांड की मिलान की गई फ़ाइलों की संख्या से बहुत कम होगी। कमांड लाइन उसी तरह से बनाई गई है जिस तरह से xargs अपनी कमांड लाइन बनाता है। कमांड के भीतर '{}' के केवल एक उदाहरण की अनुमति है। कमांड को शुरुआती डायरेक्टरी में निष्पादित किया जाता है।

मैंने भी कोशिश की:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+

क्या आपने +अंत में भागने की कोशिश की है ? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
जयहेनड्रेन

3
आप GNU के पुराने संस्करण का उपयोग कर रहे होंगे find। हालाँकि यह -exec cmd {} +वैरिएंट POSIX है और 80 के दशक से उपलब्ध है, GNU ने इसे हाल ही में (अपेक्षाकृत) जोड़ा (2005)। क्या find --versionबताता है?
स्टीफन चेजालस

2
@ Koveras, यह तब होगा। -exec {} +2005 में 4.2.12 में जोड़ा गया था। पुराने GNU में पाया जाता है, आप -print0 | xargs -r0कुछ ऐसा ही पाने के लिए (गैर-POSIX) का उपयोग कर सकते हैं । 4.11994 से है।
स्टीफन चेज़लस

1
JRFerguson ने बताया (एक उत्तर में जो हटा दिया गया है) कि -nameपैटर्न तर्क को उद्धृत किया जाना चाहिए -name "*.c" -o -name "*.h":। यह सच है, हालांकि यह -execत्रुटि से संबंधित नहीं है । आप देखेंगे कि अन्य सभी उत्तरों ने वाइल्डकार्ड को उद्धरणों में डाल दिया है, हालांकि केवल गिल्स ने इसका उल्लेख किया है। … (Cont'd)
G-Man ने कहा कि मोनिका '

1
(Cont'd)… jlliagre का उत्तर -name "*.[ch]"स्पष्टीकरण के बिना नाम की अभिव्यक्ति को ध्वस्त कर देता है। यह कमांड लाइन को सरल बनाने और विशेष रूप से, लाभ को समाप्त करने के लाभ हैं  -o। जिन भावों को सम्‍मिलित किया गया है, -oवे सही पाने के लिए कठिन हैं। तुम्हारा होना गलत है; यदि आपकी कमांड ठीक है, तो यह त्रुटि नहीं करता है (जैसा कि गिल्स के उत्तर में है), यह grepकेवल .hफाइलों पर चलेगा । आपको करने की आवश्यकता है '(' -name '*.c' -o -name '*.h' ')'
जी-मैन का कहना है कि 'मोनिका'

जवाबों:


18

आपको अपने द्वारा उपयोग किए जाने वाले एकल उद्धरणों को निकालने की आवश्यकता है {}। कमांड को इस तरह सरल बनाया जा सकता है:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +

आप एक पुरातन GNU संस्करण का उपयोग करना चाहिए, यह अभी भी काम करना चाहिए:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;

उफ़, वे उद्धरण नहीं backticks होना चाहिए थे।
डेविड केनेडी

उद्धरण बेकार होगा क्योंकि {}शेल का कोई विशिष्ट अर्थ नहीं है।
jlliagre

मैन पेज खोजने से: "स्ट्रिंग '{}' को वर्तमान फ़ाइल नाम से बदल दिया जाता है जिसे हर जगह संसाधित किया जाता है यह कमांड के तर्कों में होता है, न कि केवल उन तर्कों में जहां यह अकेला है, जैसा कि खोज के कुछ संस्करणों में है। ये दोनों। कंस्ट्रक्शन को शेल द्वारा विस्तार से बचाने के लिए ('' ') के साथ भाग जाने या उद्धृत करने की आवश्यकता हो सकती है।' '
डेविड केनेडी

1
मैंने वास्तव में पढ़ा है कि मैनुअल पेज में, लेकिन तथ्य यह है कि कोई भी शेल नहीं है जिसके बारे में मुझे पता है कि घुंघराले ब्रेस को उद्धृत करने की आवश्यकता है। आप किस खोल का उपयोग कर रहे हैं?
जूलियाग्रे

दे घुमा के। उद्धरण के साथ या इसके बिना मुझे वैसे भी त्रुटि मिलती है।
डेविड केनेडी

10

"लापता तर्क -exec" आमतौर पर इसका मतलब है कि तर्क - execअपने टर्मिनेटर को याद कर रहा है। टर्मिनेटर या तो सिर्फ चरित्र युक्त एक तर्क होना चाहिए ;(जो एक शेल कमांड में उद्धृत करने की आवश्यकता है, तो यह आम तौर पर लिखा है \;या ';'), या लगातार दो तर्क युक्त {}और +

स्टीफन चेज़ेलस ने पहचाना कि आप GNU के पुराने संस्करण का उपयोग कर रहे हैं, जो -exec … {} +केवल समर्थन नहीं करता है -exec {} \;। हालांकि जीएनयू की देर एडॉप्टर था -exec … {} +, मैं सिफारिश करते हैं कि आप एक कम प्राचीन उपकरण सूट (जैसे मिल Cygwin , जो Git भी शामिल है और भी बहुत कुछ शामिल है, या GNUwin32 , जो Git का अभाव है लेकिन बुरा-कर्मचारी-की कोशिश कर नहीं है -to-use-linux-but-we-impose-windows वाइब जो साइगविन देता है)। इस सुविधा को संस्करण 4.2.12 में जोड़ा गया था, 9 साल पहले (यह GNU findPOSIX-compliant बनाने के लिए अंतिम पहचान की गई विशेषता थी )।

यदि आप किसी पुराने जीएनयू खोज करने के लिए छड़ी करने के लिए चाहते हैं, तो आप उपयोग कर सकते हैं -print0के साथ xargs -0एक इसी तरह की सुविधा प्राप्त करने के लिए: वर्गीकृत किया आदेश निष्पादन, मनमाने ढंग से फ़ाइल नाम का समर्थन।

find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null

हमेशा findकमांड लाइन पर वाइल्डकार्ड का उद्धरण दें । अन्यथा, यदि आप .cफ़ाइलों से युक्त निर्देशिका से इस आदेश को चलाने के लिए होते हैं, तो निर्गत को वर्तमान निर्देशिका में फ़ाइलों *.cकी सूची में विस्तारित किया जाएगा .c

जोड़ने /dev/nullके लिए grepकमांड लाइन है कि ग्रेप हमेशा फ़ाइल नाम प्रिंट होगा सुनिश्चित करने के लिए एक चाल है, भले ही है findएक भी मैच खोजने के लिए होता है। जीएनयू खोजने के साथ, विकल्प पारित करने के लिए एक और तरीका है -H


1
खराब कर्मचारी-उपयोग-से-उपयोग-लिनेक्स-लेकिन-वी-थोप-विंडोज वाइब का क्या मतलब है जो साइबरविन देता है?
डेविड केनेडी

GNUwin32 की उम्मीद नहीं है :(
डेविड केनेडी

प्रश्न पर मेरी टिप्पणी (ओं) को देखें।
जी-मैन का कहना है कि 'मोनिका'

सेमी के आसपास के उद्धरण एक package.json स्क्रिप्ट के भीतर से काम करते हैं।
bjj

2

अगर एक कमांड जैसे

find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +

त्रुटि देता है

find: missing argument to -exec

संभावित कारण बहुत पुराना GNU है findजो वाक्य रचना का समर्थन नहीं करता है -exec mycommand {} +। उस स्थिति में कम प्रदर्शन प्रतिस्थापन को चलाना है -exec mycommand {} \;जो कि mycommandप्रत्येक लक्षित लक्ष्य के लिए एक बार चलेगा बजाय कई लक्ष्यों को इकट्ठा करने और mycommandबस एक बार चलाने के लिए ।

हालांकि, GNU findउदाहरण के लिए समर्थन नहीं करता है

find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +

क्योंकि GNU अधिक सामान्य के बजाय findकेवल शाब्दिक संयोजन का समर्थन करता है । ध्यान दें कि ब्रेसिज़ और चरित्र के बीच कुछ भी नहीं हो सकता है । यदि आप यह कोशिश करते हैं, तो आपको वही त्रुटि मिलेगी:{} +{} additional parameters ++

find: missing argument to -exec

वर्कअराउंड सिंटैक्स का उपयोग करना है {} additional parameters \;जो काम करता है लेकिन हर पाए गए लक्ष्य के लिए एक बार कमांड निष्पादित करेगा। यदि आपको जीएनयू के साथ अधिक प्रदर्शन की आवश्यकता है, तो आपको findएक रैपर स्क्रिप्ट लिखनी होगी जो दिए गए तर्कों को अतिरिक्त मापदंडों को जोड़ सकती है। कुछ इस तरह

#!/bin/bash
exec mycommand "$@" additional parameters

काफी अच्छा होना चाहिए। या, यदि आप अस्थायी फ़ाइल नहीं बनाना चाहते हैं, तो आप इस तरह के मापदंडों के क्रम को बदलने के लिए वन-लाइनर का उपयोग कर सकते हैं:

find . -type f -and -name "*.ttf" -exec bash -c 'mycommand "$@" extra arguments' {} +

जो निष्पादित करेगा mycommand {list of ttf files} extra arguments। ध्यान दें कि -cझंडे के बाद आपको बैश के लिए विशेष वर्णों से बचने के लिए दोहरी आवश्यकता हो सकती है ।


(१) ऊपर का वह भाग जो वास्तव में इस प्रश्न का उत्तर देता है, पहले से ही अन्य लोगों द्वारा दिया गया था। (२) आप जो वर्णन कर रहे हैं वह GNU में कोई दोष या कमी नहीं है find, बल्कि POSIX द्वारा निर्दिष्ट सही व्यवहार है ।
जी-मैन का कहना है कि 'मोनिका'

1
+1 आखिरकार, कोई ऐसा व्यक्ति जो जवाब देता है कि अतिरिक्त पैरामीटर काम क्यों नहीं करते हैं! यह POSIX परिभाषा में कमी की तरह लगता है।
जोनाथन

यदि आपने GNU findकर लिया है तो आपको शायद GNU मिल गया है cp। इस मामले में आप निष्पादन स्ट्रिंग के अंत में find ... -exec cp --target-directory ~/.fonts {} +रख सकते हैं {}
रोइमा

1

find . -type f -perm 0777 -exec chmod 644 {}\;

त्रुटि मिली find: missing argument to ``-exec'

के बीच जगह जोड़ना {}और \इसे ठीक करना:

find . -type f -perm 0777 -print -exec chmod 644 {} \;


1
findप्रश्न में कमांड में ऐसा कोई मुद्दा नहीं है ।
Kusalananda

प्रश्न में, यह ठीक नहीं है, कि मैं समझ गया था, लेकिन समस्या एक ही है "खोज:` `-exec 'के लिए लापता तर्क", समस्या अलग -2 कारण से हो सकती है, मैंने जवाब दिया क्योंकि मैंने एक ही समस्या बयान देखा था।
श्रीपूल

@ कुसलानंद अच्छा दु: ख, नोब ने रिपोर्ट की गई त्रुटि के लिए एक समाधान प्रदान किया जो ओपी द्वारा प्रश्न के शीर्षक और शरीर दोनों में बताया गया है।
bvj

@ बीवीजे प्रश्न विकल्प के +रूप के साथ स्पष्ट रूप से संबंधित -execहै find। यह उत्तर एक समस्या को ठीक कर रहा है जो प्रश्न पूछने वाले उपयोगकर्ता के पास नहीं है।
Kusalananda

-1

मेरे पास अतीत में निष्पादन सिंटैक्स के साथ सिरदर्द का मेरा हिस्सा था। अधिकांश दिनों में अब मैं अच्छे बैश के सिंटैक्स पसंद करता हूँ:

for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done

इसकी कुछ सीमाएँ हैं जब आप फ़ाइलों को एक समूह के रूप में व्यवहार करना चाहते हैं, क्योंकि प्रत्येक का क्रमिक रूप से मूल्यांकन किया जाता है, लेकिन आप आउटपुट को कहीं और ठीक कर सकते हैं


1
हालांकि यह काम करने के लिए शुद्ध-खोज संस्करण की तुलना में काफी कम उपयोगी है, क्योंकि यह नाम में व्हाट्सएप के साथ फाइलों को सही ढंग से संभाल नहीं सकता है।
इटन रिस्नर

5
नहीं, यह मत करो। जैसे ही फाइलों में स्थान और अन्य "अजीब" अक्षर होते हैं, यह टूट जाता है। यह भी अधिक जटिल और धीमा है find … -exec … \;, इसलिए इसका उपयोग करने का कोई कारण नहीं है, भले ही आपको पता हो कि आपके फ़ाइल नाम tame हैं।
गिल्स एसओ- बुराई को रोकना '

यह मेरी स्थिति के लिए सहायक था जहाँ मुझे फ़ाइल नामों के आधार पर तर्क की कई पंक्तियाँ चलाने की आवश्यकता थी (जैसे चार्ट हटाना, निर्देशिका बनाना और फिर फ़ाइलें स्थानांतरित करना)। exec5 में से कई चीजों को करने के लिए बहुत सारी चीजें ढूंढने की कोशिश में मैं इस पर खर्च करना चाहता था। मेरी फ़ाइल के नाम tame थे और इसने मेरी समस्या हल कर दी :)
gMale
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.