खोजने में निष्पादन के साथ अर्धविराम (;) बनाम प्लस (+) का उपयोग करना


159

उपयोग करने के बीच आउटपुट में अंतर क्यों है

find . -exec ls '{}' \+

तथा

find . -exec ls '{}' \;

मुझे मिला:

$ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1

जवाबों:


249

यह सबसे अच्छा उदाहरण के साथ चित्रित किया जा सकता है। मान लें कि findइन फ़ाइलों को चालू करता है:

file1
file2
file3

-execएक अर्धविराम ( find . -exec ls '{}' \;) के साथ प्रयोग , निष्पादित करेगा

ls file1
ls file2
ls file3

लेकिन अगर आप इसके बजाय एक प्लस चिह्न ( find . -exec ls '{}' \+) का उपयोग करते हैं , तो जितने संभव हो उतने फाइलनाम एक ही आदेश के तर्क के रूप में पारित किए जाते हैं:

ls file1 file2 file3

फ़ाइलनामों की संख्या केवल सिस्टम की अधिकतम कमांड लाइन की लंबाई तक सीमित है। यदि कमांड इस लंबाई से अधिक है, तो कमांड को कई बार कहा जाएगा।


1
धन्यवाद। परिणामी फ़ाइलों को क्रमबद्ध करने के लिए यह बहुत उपयोगी है: -maxdepth 1 -type f -mtime -1 -exec ls -Exr {} \ +
fbas

1
बेवकूफ प्रश्न: मैं सूचना है कि +के साथ जुड़े -execहमेशा बच रहा है, लेकिन +साथ जुड़े -mtimeनहीं है। क्या आप इसका कारण जानते हैं? मुझे लगता है कि यह भागने से ;जुड़ी आदत है -exec
केविनरपे

3
@kevinarpe वास्तव में, मैं इसे आदत से चाक कर दूंगा ;। भागने के लिए कभी भी यह जरूरी नहीं समझा जा सकता है+
मार्टिन

36

अब तक के सभी उत्तर सही हैं। मैं इसे एक स्पष्ट (मेरे लिए) व्यवहार के प्रदर्शन के रूप में प्रस्तुत करता हूं जो echoइसके बजाय उपयोग करने के लिए वर्णित है ls:

अर्धविराम के साथ, कमांड echoको एक बार प्रति फ़ाइल (या अन्य फाइलसिस्टम ऑब्जेक्ट) पाया जाता है:

$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh

प्लस के साथ, कमांड echoको केवल एक बार कहा जाता है। पाया गया हर फ़ाइल एक तर्क के रूप में पारित किया जाता है।

$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh

यदि findबड़ी संख्या में परिणाम सामने आते हैं, तो आप पा सकते हैं कि कमांड को तर्कों की संख्या पर चोक कहा जा रहा है।


1
केवल एक संख्या में परिणाम जोड़ना नहीं चाहिए जो इसे शेल में पास करने के लिए सुरक्षित बनाता है? कम से कम क्या xargsकरना है ... सिद्धांत रूप में यह बहुत अधिक तर्कों के लिए कभी नहीं घुटता है।
रमनो

1
@ रमनो: मैंने देखा है find(और xargs) सोलारिस पर अधिक तर्कों का उपभोग किया जा सकता है। xargs(और find) में जीएनयू के findutils` अधिक समझदारी से व्यवहार करने के लिए लग रहे हैं, लेकिन सभी के जीएनयू उपयोग करता है।
जॉन्सवेब

2
@ जोशिवेब, सभी POSIX findतर्कों की संख्या पर सीमा तक पहुंचने से बचने की कोशिश करेंगे। और इसमें सोलारिस '(10 कम से कम) शामिल हैं। जहां यह विफल हो सकता है यदि आप कुछ ऐसा करते हैं find ... -exec ksh -c 'cmd "$@" "$@"' sh {} +या find ... -exec ksh -c 'files="$*" cmd "$@"' sh {} +, लेकिन findवास्तव में इसके लिए दोषी नहीं ठहराया जा सकता है। ध्यान दें कि GNU समर्थन findके लिए अंतिम findकार्यान्वयन में से एक था +(GNU सिस्टम में पोर्ट स्क्रिप्ट के लिए एक दर्द होने के लिए)।
स्टीफन चेजलस

19

से man find:

-exec कमांड;

निष्पादित आदेश; सच है अगर 0 स्थिति वापस आ गई है। निम्नलिखित सभी तर्कों को ''; '' युक्त तर्क तक कमांड के तर्क के लिए लिया जाता है; सामना किया है। स्ट्रिंग '{}' को वर्तमान फ़ाइल नाम से बदल दिया जाता है जिसे हर जगह संसाधित किया जाता है यह कमांड के तर्कों में होता है, न कि केवल उन तर्कों में जहां यह अकेला है, जैसा कि कुछ संस्करणों में पाया जाता है। इन दोनों निर्माणों को शेल द्वारा विस्तार से बचाने के लिए ('\') के साथ भाग जाने या उद्धृत करने की आवश्यकता हो सकती है। '-Exec' विकल्प के उपयोग के उदाहरणों के लिए EXAMPLES सेकंड अनुभाग देखें। निर्दिष्ट कमांड प्रत्येक मिलान की गई फ़ाइल के लिए एक बार चलाई जाती है। कमांड को शुरुआती डायरेक्टरी में निष्पादित किया जाता है। वहाँ -exec विकल्प के उपयोग के आसपास सुरक्षा संबंधी समस्याएं नहीं हैं;

-exec कमांड {} +

-Exec विकल्प का यह संस्करण चयनित फ़ाइलों पर निर्दिष्ट कमांड चलाता है, लेकिन कमांड लाइन अंत में प्रत्येक चयनित फ़ाइल नाम को जोड़कर बनाया गया है ; कमांड की कुल संख्या का मिलान की गई फ़ाइलों की संख्या से बहुत कम होगा। कमांड लाइन उसी तरह से बनाई गई है जिस तरह से xargs अपनी कमांड लाइन बनाता है। कमांड के भीतर '{}' के केवल एक उदाहरण की अनुमति है। कमांड को शुरुआती डायरेक्टरी में निष्पादित किया जाता है।

इसलिए, जिस तरह से मैं इसे समझता हूं, वह \;प्रत्येक फ़ाइल के लिए एक अलग कमांड निष्पादित करता है find, जबकि \+फाइलों को जोड़ता है और उन सभी पर एक ही कमांड निष्पादित करता है। \, एक एस्केप वर्ण है, तो यह है:

ls testdir1; ls testdir2 

बनाम

ls testdir1 testdir2

मेरे शेल में ऊपर करने से आपके प्रश्न में आउटपुट का पता चलता है।

आप कब उपयोग करना चाहेंगे इसका उदाहरण \+

मान लीजिए दो फाइलें, 1.tmpऔर 2.tmp:

1.tmp:

1
2
3

2.tmp:

0
2
3

के साथ \;:

 find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.

यदि आप उपयोग करते हैं \+(परिणामों को संक्षिप्त करने के लिए find):

find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30

तो इस मामले में यह diff 1.tmp; diff 2.tmpऔर के बीच का अंतर हैdiff 1.tmp 2.tmp

ऐसे मामले हैं जहां \;उपयुक्त है और \+आवश्यक होगा। इसके \+साथ प्रयोग करना rmएक ऐसा उदाहरण है, जहाँ यदि आप बड़ी संख्या में फ़ाइलों को निकाल रहे हैं तो प्रदर्शन (गति) बेहतर होगा \;


मैन पेज भी पढ़ सकता हूं। और मैंने किया, लेकिन मुझे नहीं लगता कि मैं उपयोग करने के बीच के अंतर को समझता हूं; बनाम +
अंकुर अग्रवाल

मुझे नहीं लगता कि -1 उचित था, मैंने अपने आदमी को अंडरस्टैंडिंग समझाया। मैं सिर्फ आदमी की नकल नहीं करता और छोड़ देता। लेकिन मैंने एक बेहतर उदाहरण को शामिल करने के लिए अपनी प्रतिक्रिया संपादित की है।
matchew

10

findविशेष वाक्यविन्यास है। आप {}उनका उपयोग इसलिए करते हैं क्योंकि उनके पास अर्थ है कि पाया फ़ाइल के पथनाम के रूप में और (अधिकांश) गोले उन्हें अन्यथा व्याख्या नहीं करते हैं। आपको बैकस्लैश की आवश्यकता है \;क्योंकि अर्धविराम का अर्थ शेल है, जो इसे findप्राप्त करने से पहले खा लेता है। तो क्या findAFTER खोल को देखने के लिए, तर्क कार्यक्रम में C प्रोग्राम के लिए पारित किया गया है, है

"-exec", "rm", "{}", ";"

लेकिन आपको \;कमांड लाइन पर शेल के माध्यम से तर्क के लिए अर्धविराम प्राप्त करने की आवश्यकता है।

आप दूर हो सकते हैं \{\}क्योंकि शेल-उद्धृत व्याख्या \{\}सिर्फ है {}। इसी तरह, आप '{}' का उपयोग कर सकते हैं।

आप जो नहीं कर सकते उसका उपयोग है

 -exec 'rm {} ;'

क्योंकि शेल व्याख्या करता है कि एक तर्क के रूप में ,

"-exec", "rm {};"

और rm {} ;एक कमांड का नाम नहीं है। (कम से कम जब तक कोई वास्तव में चारों ओर नहीं है।)

अपडेट करें

अंतर है

$ ls file1
$ ls file2

तथा

$ ls file1 file2

+एक कमांड लाइन पर नाम catenating है।


1
मैं समझ गया आप क्या कह रहे हैं। मैं पूछ रहा हूं कि उपयोग करने के बीच अंतर क्या है; बनाम +
अंकुर अग्रवाल

1
क्षमा करें, लेकिन क्या आपने मेरे प्रश्न या मेरी टिप्पणी को ध्यान से पढ़ा? हो सकता है मुझे इसकी पुन: पुष्टि करने की आवश्यकता हो। जब मैं खोजने में निष्पादन के साथ प्लस का उपयोग करता हूं, तो मुझे खोजने में निष्पादन के साथ अर्धविराम का उपयोग करने पर एक अलग ओ / पी क्यों होता है?
अंकुर अग्रवाल

2
WHY के लिए यह एक उत्कृष्ट स्पष्टीकरण है कि कमांड इस तरह है, कि स्वीकृत उत्तर कवर नहीं करता है। धन्यवाद!
शेरविन यू

1

;(अर्धविराम) या +(प्लस चिह्न) के बीच का अंतर यह है कि तर्क को -exec/ के -execdirपैरामीटर में कैसे पारित किया जाता है । उदाहरण के लिए:

  • उपयोग ;करने से कई कमांड निष्पादित होंगे (प्रत्येक तर्क के लिए अलग से),

    उदाहरण:

    $ find /etc/rc* -exec echo Arg: {} ';'
    Arg: /etc/rc.common
    Arg: /etc/rc.common~previous
    Arg: /etc/rc.local
    Arg: /etc/rc.netboot
    

    निम्नलिखित सभी findतर्कों को कमांड के तर्क के लिए लिया जाता है।

    स्ट्रिंग {}को वर्तमान फ़ाइल नाम से संसाधित किया जा रहा है।

  • उपयोग +करने से कम से कम संभव कमांड निष्पादित होंगे (जैसा कि तर्क एक साथ संयुक्त हैं)। यह बहुत ही सामान्य है कि xargsकमांड कैसे काम करता है, इसलिए यह प्रति पंक्ति तर्कों की अधिकतम सीमा से अधिक बचने के लिए प्रति कमांड के रूप में कई तर्कों का उपयोग करेगा।

    उदाहरण:

    $ find /etc/rc* -exec echo Arg: {} '+'
    Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
    

    कमांड लाइन अंत में प्रत्येक चयनित फ़ाइल नाम को जोड़कर बनाई गई है।

    {}कमांड के भीतर केवल एक उदाहरण की अनुमति है।

यह सभी देखें:


-5

हम हाउसकीपिंग के लिए फाइल खोजने की कोशिश कर रहे थे।

खोजो। -सेक्स ईको {} \; कोई परिणाम नहीं होने पर रात में कमांड चलती थी।

खोजो। -exec की प्रतिध्वनि {} \ _ के परिणाम हैं और केवल कुछ ही घंटे लगे हैं।

उम्मीद है की यह मदद करेगा।


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