जब `-o` का उपयोग किया जाता है तो लिनक्स में` find` को अपेक्षित परिणाम छोड़ें?


7

लिनक्स में क्यों (डेबियन 8)

touch 1.cpp 1.h
find . -name "*.cpp" -o -name "*.h" -exec echo {} \;

आउटपुट केवल 1.hजबकि

find . -name "*.cpp" -o -name "*.h"

आउटपुट दोनों? यह एक बग या सुविधा है?

जवाबों:


2

मुझे लगता है कि एक बार जब आप -orऑपरेटर का उपयोग करते हैं, तो आप तार्किक संचालन के अस्पष्ट आदेश से बचने के लिए इसे लगातार बनाए रखना चाहते हैं जब आपके पास तार्किक या से जुड़ी कई शर्तें होती हैं।

ऐसा लगता है कि -execहिस्सा दूसरे के साथ मिलकर बनाया गया है -name "*.h"

तो इसे सही ढंग से काम करने के लिए, आपको नीचे के रूप में कोष्ठक जोड़ना होगा:

find . '(' -name '*.cpp' -o -name '*.h' ')' -exec echo {} ';'

याद रखें: विशेष शैल वर्णों के रूप में व्याख्या करने से रोकने के लिए कोष्ठक को उद्धृत या बचना चाहिए।

वैकल्पिक रूप से कुछ एक्सटेंशन को एक में जोड़कर उपयोग करें -regex:

find . ! -regex ".*\.\(cpp\|h\)" -exec echo {} \;

2

न तो। यह उन विकल्पों का वाक्य विन्यास है जो "गलत" है। findक्रमिक रूप से विकसित होता है। इसलिए, यह पहली अभिव्यक्ति का मूल्यांकन करता है ( -name "*.cpp") फिर एक -oध्वज का सामना करता है । यदि पहली अभिव्यक्ति सही है, findतो दूसरे का मूल्यांकन करना जारी नहीं रहेगा ( -name "*.h" -exec echo {} \;), इसके बजाय कुछ भी नहीं करता है। तुम देखो, -oएक अभिव्यक्ति के बाद पूरा हिस्सा है। इसलिए, यह केवल उन फ़ाइलों के लिए निष्पादित किया जाता है जो दूसरी अभिव्यक्ति से मेल खाते हैं। इसलिए आप केवल 1.hफ़ाइल को देखते हैं , जो केवल दूसरी अभिव्यक्ति से गुजरती है। देखें मैनपेज देखें:

   expr1 -o expr2
          Or; expr2 is not evaluated if expr1 is true.

यह क्यों उपयोगी है? निम्नलिखित को धयान मे रखते हुए:

find /path -exec test_file_for_something {} -print \; -o -name "xyz" -exec ls -l {} \;

इस खोज विवरण में फ़ाइल test_file_for_somethingको एक पैरामीटर के रूप में दिया गया है । अब, उस आदेश के आधार पर वापसी कोड पहली अभिव्यक्ति सच है (फिर -printनिष्पादित होता है और वहां समाप्त होता है) या गलत (फिर -oध्वज के मूल्यांकन के बाद दूसरी अभिव्यक्ति )। और यदि वह सत्य है (नाम है xyz), तो -execनिष्पादित किया जाता है।

अपनी समस्या के लिए आप इसके बजाय तत्वों को एक साथ एक अभिव्यक्ति के रूप में समूह के लिए उपयोग कर सकते हैं :

find . \( -name "*.cpp" -o -name "*.h" \) -exec echo {} \;

1

कोष्ठक के साथ अपने खोज मापदंड को घेरने की कोशिश करें:

find . \( -name "*.cpp" -o -name "*.h" \) -exec echo {} \;

0

यह वह तरीका है जो इसके संचालकों के साथ काम करता है।

Http://linux.die.net/man/1/find अनुभाग OPERATORS देखें

ऑपरेटरों

पूर्ववर्ती घटने के क्रम में सूचीबद्ध: (expr) बल पूर्ववर्तीता। चूंकि कोष्ठक खोल के लिए विशेष हैं, इसलिए आपको सामान्य रूप से उन्हें उद्धृत करना होगा। इस मैनुअल पृष्ठ के कई उदाहरण इस उद्देश्य के लिए बैकस्लैश का उपयोग करते हैं: '(...)' के बजाय (...) '। ! expr सच है अगर expr गलत है। इस चरित्र को आमतौर पर शेल द्वारा व्याख्या से सुरक्षा की आवश्यकता होगी।

के रूप में एक ही expr नहीं! expr, लेकिन POSIX अनुरूप नहीं। expr1 expr2 एक पंक्ति में दो अभिव्यक्तियों को एक निहित "और" के साथ जोड़ा जाना है; अगर expr1 गलत है, तो expr2 का मूल्यांकन नहीं किया जाता है। expr1 -a expr2 expr1 expr2 के समान। expr1 -और expr2 एक ही expr1 expr2 के रूप में ही है, लेकिन POSIX अनुरूप नहीं। expr1 -o expr2 या; अगर expr1 सच है, expr2 का मूल्यांकन नहीं किया जाता है। expr1 -or expr2 के रूप में एक ही expr1 -o expr2, लेकिन POSIX अनुरूप नहीं। expr1, expr2 सूची; expr1 और expr2 दोनों का मूल्यांकन हमेशा किया जाता है। Expr1 का मूल्य त्याग दिया गया है; सूची का मान expr2 का मान है। अल्पविराम ऑपरेटर कई अलग-अलग प्रकार की चीजों की खोज के लिए उपयोगी हो सकता है, लेकिन केवल एक बार फाइलसिस्टम पदानुक्रम का पता लगाना। -Fprintf क्रिया का उपयोग विभिन्न मिलान वाली वस्तुओं को कई अलग-अलग आउटपुट फाइलों में सूचीबद्ध करने के लिए किया जा सकता है।

यह आपको वह परिणाम देना चाहिए जो आप चाहते हैं:

खोजो। \ _-name '* .cpp' -o -name '* .h' \ '-exec इको {} \;

आपकी आज्ञा यह कर रही है (कमांड काम नहीं करेगी, बस आपको तर्क दिखाने के लिए):

खोजो। -name '* .cpp' (-o -name '* .h' -exec गूंज {} \);)

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