bash - क्या मैं कर सकता हूँ: खोज… -इस प्रकार && कि?


23

क्या दो शेल कमांड को तार्किक रूप से संयोजित करने का एक तरीका है जो खोज - निष्पादन के साथ लगाया जाता है ?

उदाहरण के लिए, सभी .csv फ़ाइलों को प्रिंट करने के लिए जिसमें स्ट्रिंग फू एक साथ होती है इसकी घटना के साथ मैं यह करना चाहूंगा:

find . -iname \*.csv -exec grep foo {} && echo {} \;

लेकिन बैश ने '' -सेक्स '' के लिए लापता तर्क के साथ शिकायत की


2
आप -execअनुक्रम में 2 का उपयोग कर सकते हैं या एकल का उपयोग कर सकते हैं -exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;
19 जून को jw013

इसने मुझे बार-बार उलझाया है: मैं हमेशा उम्मीद करता हूं कि sh(इस मामले में {}) पहले तर्क पारित किया जाएगा $1और $0कुछ ऐसा होगा sh। लेकिन वास्तव में, आप सही हैं, पहला तर्क जैसा दिखता है $0। पहला तर्क होने के कारण इनवोकिंग कमांड का नाम सिर्फ एक कन्वेंशन है, जो इन मामलों में स्वचालित रूप से लागू नहीं होता है।
डबियसजिम

शायद इस सवाल के साथ विलय कर दिया जाए: unix.stackexchange.com/q/18077/4801
dubiousjim

जवाबों:


24

-execएक विधेय है जो एक कमांड चलाता है (शेल नहीं) और कमांड के परिणाम (शून्य या गैर-शून्य निकास स्थिति) के आधार पर सही या गलत का मूल्यांकन करता है

इसलिए:

find . -iname '*.csv' -exec grep foo {} \; -print

अगर फ़ाइल में फ़ाइल मिलती है तो फ़ाइल पथ प्रिंट करेगा grep। इसके बजाय -printआप एक और -execविधेय या किसी अन्य विधेय का उपयोग कर सकते हैं

find . -iname '*.csv' -exec grep foo {} \; -exec echo {} \;

यह भी देखें !और -oनिषेध और के लिए ऑपरेटरों को खोजने या

वैकल्पिक रूप से, आप एक शेल शुरू कर सकते हैं:

find . -iname '*.csv' -exec sh -c '
   grep foo "$1" && echo "$1"' sh {} \;

या हर फ़ाइल के लिए एक शेल शुरू करने से बचने के लिए:

find . -iname '*.csv' -exec sh -c '
  for i do
    grep foo "$i" && echo "$i"
  done' sh {} +

10

आप जिस समस्या का सामना कर रहे हैं वह यह है कि शेल पहले कमांड लाइन को पार्स करता है, और &&ऑपरेटर द्वारा अलग किए गए दो सरल कमांड देखता है : find . -iname \*.csv -exec grep foo {}और echo {} \;,। का हवाला देते हुए &&( find . -iname \*.csv -exec grep foo {} '&&' echo {} \;) नजरअंदाज कि है, लेकिन अब आदेश द्वारा निष्पादित findकी तरह कुछ है grepतर्क के साथ foo, wibble.csv, &&, echoऔर wibble.csv। आपको findएक शेल चलाने के लिए निर्देश देने की आवश्यकता है जो &&ऑपरेटर की व्याख्या करेगा :

find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;

ध्यान दें कि इसके बाद पहला तर्क sh -c SOMECOMMANDहै $0, नहीं $1

आप कमांड इनवॉइस को समूहीकृत करके हर फ़ाइल के लिए शेल प्रक्रिया के स्टार्टअप समय को बचा सकते हैं -exec … +। प्रसंस्करण में आसानी के लिए, कुछ डमी मूल्य को पास करें $0ताकि "$@"फ़ाइल नामों की गणना हो सके।

find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +

यदि शेल कमांड केवल दो कार्यक्रमों द्वारा अलग किया गया है &&, तो findअपने आप से काम कर सकते हैं: दो लगातार -execक्रियाएं लिखें , और दूसरा केवल तभी निष्पादित किया जाएगा जब पहले वाला स्थिति 0 से बाहर निकलता है।

find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;

(मुझे लगता है कि grepऔर echoउदाहरण के उद्देश्य के लिए कर रहे हैं, के रूप में -exec echoद्वारा प्रतिस्थापित किया जा सकता है -printऔर परिणामी आउटपुट वैसे भी विशेष रूप से उपयोगी नहीं है।)


2
मैं इसके लिए "$ 0" का उपयोग करने से बचता हूं, क्योंकि इसका उपयोग शेल द्वारा त्रुटि संदेशों को प्रदर्शित करने के लिए भी किया जाता है। उदाहरण के लिए, आप एक भ्रामक ./some-file: grep: command not foundत्रुटि संदेश देख सकते हैं । -exec find sh -c '... "$1"' sh {} \;मुद्दा नहीं होता। आपकी दूसरी खोज कमांड में एक टाइपो (संबंधित) है।
स्टीफन चेजेलस

3

इस विशिष्ट मामले में मैं करूंगा:

find . -iname \*.csv -exec grep -l foo \{\} \;

या अगर आपके पास ऐक है :

ack -al -G '.*\.csv' foo

आपके वास्तविक प्रश्न का उत्तर देने के लिए, कुछ इस तरह काम कर सकता है:

find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;


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

सभी अधिक प्रयास करने के लिए और इसे ठीक से
gckp

1
jw013 का विकल्प (प्रश्न के लिए एक टिप्पणी में दिया गया) इस संबंध में अधिक सुरक्षित है। (बस ध्यान दिया गया कि गिल्स और स्टीफन के उत्तर एक ही तकनीक का उपयोग करते हैं।)
डबियसजिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.