muru का उत्तर उपयुक्त और अच्छी तरह से उन मामलों के लिए उपयुक्त है जहाँ हम फ़ाइल के मिलने पर कुछ प्रिंट करना चाहते हैं। सामान्य मामले के लिए जब हम बाहरी कमांड निष्पादित करना चाहते हैं, जैसे कि echo
, हम -exec
ध्वज का उपयोग कर सकते हैं ।
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
इस {}
भाग को तर्कों के बीच -exec
और कमांड में फ़ाइल नाम दिया \;
जाता है। \
पहले ध्यान दें ;
- यह शेल को गलत तरीके से व्याख्या करने से रोकता है closing शेल क्लोजिंग सेमीकोलन में कमांड के अंत का संकेत देता है, लेकिन जब स्लैश से बच जाता है, शेल इसे find
कमांड को पारित करने के लिए शाब्दिक पाठ के रूप में व्यवहार करेगा और कमांड को खोजने के लिए यह -exec
ध्वज के तर्कों को बंद करने का काम करेगा।
if found do this; else do that
सॉर्ट के सशर्त निर्माण के लिए , हम कमांड सबस्टेशन $()
और test
कमांड (उर्फ [
) का उपयोग कर सकते हैं :
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
दान की टिप्पणी को संबोधित करते हुए
दान टिप्पणियों में पूछा:
गूंज नहीं होगा "मैंने पाया {}" गूंज से बेहतर होगा "मैंने पाया" {}? शायद इको के लिए यह ठीक है, लेकिन अगर कोई कमांड को कॉपी करता है और इको को दूसरी कमांड से बदलता है, तो उन्हें समस्या हो सकती है
आइए पहले समस्या को समझते हैं। आमतौर पर, गोले में शब्द-विभाजन की अवधारणा होती है, जिसका अर्थ है कि अछूता चर और स्थितिगत मापदंडों का विस्तार और अलग-अलग वस्तुओं के रूप में इलाज किया जाएगा। उदाहरण के लिए, यदि आप चर है var
और इसमें hello world
पाठ, जब आप कर touch $var
खोल इसे नीचे दो अलग-अलग आइटम में टूट जाएगा hello
और world
और touch
समझ जायेंगे कि जैसे कि आप 2 अलग फ़ाइलें बनाने के लिए कोशिश कर रहे थे; यदि आप करते हैं touch "$var"
, तो शेल hello world
एक इकाई के रूप में माना जाएगा , और touch
केवल एक फ़ाइल बनाएगा। यह समझना महत्वपूर्ण है कि यह केवल गोले के काम करने के कारण होता है।
इसके विपरीत, find
इस तरह के व्यवहार से पीड़ित नहीं होता है, क्योंकि कमांड find
स्वयं द्वारा संसाधित होते हैं और execvp()
सिस्टम कॉल द्वारा निष्पादित होते हैं, इसलिए इसमें कोई शेल शामिल नहीं है। जबकि घुंघराले ब्रेसिज़ का गोले में विशेष अर्थ होता है, क्योंकि वे find
कमांड के बीच में दिखाई देते हैं , और शुरुआत में नहीं, वे इस मामले में शेल के लिए कोई विशेष अर्थ नहीं रखते हैं। यहाँ एक उदाहरण है। आइए कुछ कठिन फ़ाइलनाम बनाएं और उन्हें stat
कमांड के तर्क के रूप में पारित करने का प्रयास करें ।
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
जैसा कि आप देख सकते हैं, stat
मुश्किल फाइलनाम को पूरी तरह से ठीक से प्राप्त करता है find
, जो कि मुख्य कारणों में से एक है क्योंकि यह पोर्टेबल स्क्रिप्ट में उपयोग के लिए अनुशंसित है, और विशेष रूप से उपयोगी है जब आप डायरेक्टरी ट्री को ट्रेस कर रहे हैं और संभवतः फ़ाइलनाम के साथ कुछ करना चाहते हैं। उनमें विशेष चरित्र। इसलिए, इसमें निष्पादित आदेशों के लिए घुंघराले ब्रेसिज़ को उद्धृत करना आवश्यक नहीं है find
।
यह एक अलग कहानी है जब शेल शामिल हो जाता है। कभी-कभी आपको फ़ाइल नाम को संसाधित करने के लिए शेल का उपयोग करने की आवश्यकता होती है। उस मामले में, उद्धृत करना वास्तव में मायने रखेगा, लेकिन यह महसूस करना महत्वपूर्ण है कि यह समस्या नहीं है - यह शेल है जो शब्द विभाजन करता है।
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
इसलिए जब हम शेल के भीतर उद्धृत करते हैं, तो यह काम करेगा। लेकिन फिर, यह शेल के लिए महत्वपूर्ण है, नहीं find
।
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file
/some/path
बताता है कि ढूंढना कहां शुरू करना है, लेकिन कुछ भी नहीं बताता है कि क्या देखना है। आपके जुड़े हुए उत्तर में भी। क्या मेरे लिए काम करता हैfind /some/path -name xac -print0 -quit | grep -qz . && echo found
। क्या मैं कुछ भुल गया?