कमांड खोजने के बाद कनेक्टर्स का उपयोग करना


10

मैं चाहता हूं कि मेरा बैश 'पाया' को तभी प्रिंट करे, जब कुछ मिल जाए, जो कि कमांड का उपयोग कर रहा हो। लेकिन && का उपयोग करना मदद नहीं करता है: भले ही कुछ भी नहीं मिला हो, मैं 'पाया' मुद्रित कर रहा हूं। उदाहरण:

$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa  xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found

जवाबों:


18

आप findस्वयं प्रिंट कर सकते हैं found:

find . -name xac -printf "found\n" -quit

-quitकर देगा find पहले मैच के बाद छोड़ दिया है, तो foundकेवल एक बार ज्यादा से ज्यादा प्रिंट होता है।

यूनिक्स और लिनक्स पर इसी तरह के एक धागे पर ( जब कुछ नहीं मिला तो असफल हो जाएं ), मैंने पाया गयाgrep -qz गैर-शून्य निकास स्थिति वापस करने के लिए उपयोग किया जाता है find:

find /some/path -print0 -quit | grep -qz .

जिसका उपयोग आप कंपाउंड कमांड का उपयोग करके &&या करने के लिए कर सकते हैं if:

find /some/path -print0 -quit | grep -qz . && echo found

मुझे इस थोड़ी देर में घूरना था। /some/pathबताता है कि ढूंढना कहां शुरू करना है, लेकिन कुछ भी नहीं बताता है कि क्या देखना है। आपके जुड़े हुए उत्तर में भी। क्या मेरे लिए काम करता है find /some/path -name xac -print0 -quit | grep -qz . && echo found। क्या मैं कुछ भुल गया?
जो

@ जो यहाँ मायने रखता है -print0 -quit। इससे पहले कि आप क्या डालते हैं यह इस बात पर निर्भर करता है कि आप क्या खोजना चाहते हैं। मैंने उसे यहाँ छोड़ना चुना।
मुरु

13

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

echo "I found {}"से बेहतर नहीं होगा echo "I found " {}? शायद इको के लिए यह ठीक है, लेकिन अगर कोई कमांड को कॉपी करता है और इको को दूसरी कमांड से बदलता है, तो उन्हें समस्या हो सकती है।
डैन

@ इस विषय पर टिप्पणियों में चर्चा करने के लिए बहुत लंबा था, इसलिए मैंने अपने उत्तर को संपादित किया। कृपया इसे देखें
सेर्गी कोलोडियाज़नी

1
अंत में मुझे यह समझने के लिए धन्यवाद कि अर्धविराम की आवश्यकता क्यों है। इसके अलावा, उद्धरण की महान व्याख्या।
जो ६

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