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। क्या मैं कुछ भुल गया?