खोज का उपयोग करते समय मैं कई कमांड कैसे निष्पादित कर सकता हूं?


57

मैं उन चीजों पर कई कमांड चलाने की कोशिश कर रहा हूं जो मुझे मिली हैं, मैं इसे कैसे प्राप्त कर सकता हूं?

find . -exec cmd1; cmd2

काम नहीं लगता है; इसके बजाय cmd2 चलता है cmd1 के बाद हर फाइल पर निष्पादित किया गया है।

जवाबों:


40

इस प्रदर्शन में, मैं पहली बार sh -c 'echo first; false'(या true) का उपयोग करूँगा -exec। यह कुछ आउटपुट देगा और चयनित निकास कोड प्रभाव भी होगा। फिर echo secondदूसरे के लिए इस्तेमाल किया जाएगा। मान लें कि वर्तमान निर्देशिका में एक फ़ाइल है।

$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second

इस प्रकार का एक वास्तविक कमांड दिखेगा:

find . -type f \( -exec command1 \; -false -o -exec command2 \; \)

दूसरे सेट में, भागे हुए कोष्ठक दो -execखंडों का समूह बनाते हैं। उन -falseदोनों के बीच परीक्षण की स्थिति को "गलत" और -oअगली अभिव्यक्ति (दूसरा -exec) के कारण मूल्यांकन करने के लिए मजबूर करता है -false

से man find:

expr1 expr2
एक पंक्ति में दो अभिव्यक्तियों को एक निहित "और" के साथ जोड़ा जाना है; यदि expr1 गलत है, तो expr2 का मूल्यांकन नहीं किया जाता है।

expr1 -a expr2
समान expr1 expr2।

expr1 -o expr2
या; अगर expr1 सच है, expr2 का मूल्यांकन नहीं किया जाता है।


आह हाँ, मैं भूल गया था -o
इग्नासियो वाज़क्वेज़-अब्राम्स

32

यदि आप cmd1 के बारे में बात नहीं करते हैं तो cmd2 को त्रुटि कोड के कारण चलने से रोकने में सक्षम है 0:

find . -exec cmd1 \; -exec cmd2 \;

हमेशा यह चलाने के लिए दोनों कमांड प्राप्त करने का एकमात्र विश्वसनीय तरीका findएक शेल को लागू करना है जो बाद में कमांड को क्रम में चलाएगा:

find . -exec bash -c 'cmd1; cmd2' filedumper {} \;

2

यदि आप ऐसी स्क्रिप्ट बनाने से गुरेज नहीं करते हैं जो cmd1 और cmd2 करती है, तो यह सिर्फ यही है:

find . -exec myscript {} \;

या

find . -exec myscript {} +

उपयोग \; या + इस बात पर निर्भर करता है कि क्या myscript एक समय में एक से अधिक फ़ाइल को संभाल सकती है (यदि बालों में जगह है, तो फ़ाइल नाम आदि)।

एक पटकथा में जो आप कर रहे थे, उसे मेरे अनुभव में लाना, लगभग हमेशा इसके लायक रहा है। यदि आपको इसे एक बार करना है, तो आपको इसे फिर से करना होगा।

लेकिन एक साफ चाल खोजने डाल करने के लिए है अंदर स्क्रिप्ट:

if [ $# -gt 0 ]; then
    for each; do
        touch $each
    done
else
    find . -exec $0 {} +
fi

फिर myscript आपके लिए काम करने के लिए तर्क के रूप में जो भी फाइल देता है, उस पर काम करता है, लेकिन अगर आप इसे कोई तर्क नहीं देते हैं, तो यह वर्तमान dir से पता चलता है, और फिर खुद को मिली फाइलों पर कॉल करता है। यह इस तथ्य के इर्द-गिर्द मिलता है कि आपके स्क्रिप्ट में परिभाषित शेल-फ़ंक्शन को शेल फ़ंक्शन नहीं कह सकता।


0

मैं बहुत किस्मत के बिना पिछले दोनों समाधानों की कोशिश कर रहा हूं। यह एक मेरे लिए अच्छी तरह से काम किया है:

$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done

यदि फ़ाइलों की सूची बहुत बड़ी है तो यह काम नहीं करेगा।
एलेक्स

-3

कोशिश आदेश:

sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l

4
एह, यह एक अच्छा विचार नहीं है। *में -execहिस्सा मौजूदा निर्देशिका में सभी फ़ाइलों को विस्तार होगा। खासकर जब दौड़ रहा हो sudo
slhck
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.