मुझे .svn निर्देशिकाओं को अनदेखा करने के लिए `find` कैसे मिल सकता है?


227

मैं अक्सर findस्रोत कोड के माध्यम से खोज करने के लिए कमांड का उपयोग करता हूं , फाइलें हटाता हूं , जो भी हो। सावधानी से, क्योंकि सबवर्सन अपनी .svn/text-base/निर्देशिका में प्रत्येक फ़ाइल के डुप्लिकेट को संग्रहीत करता है मेरी सरल खोजों को बहुत सारे डुप्लिकेट परिणाम मिलते हैं। उदाहरण के लिए, मैं uintएकाधिक messages.hऔर messages.cppफ़ाइलों में पुन: खोज करना चाहता हूं :

# find -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./.svn/text-base/messages.cpp.svn-base:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;
./virus/.svn/text-base/messages.cpp.svn-base:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.cpp.svn-base:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.h.svn-base:    void _progress(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    uint        _scanCount;

मैं निर्देशिकाओं findको अनदेखा करने के लिए कैसे कह सकता हूं .svn?


अद्यतन : यदि आप अपने SVN क्लाइंट को संस्करण 1.7 में अपग्रेड करते हैं तो यह कोई समस्या नहीं है।

सबवर्सन 1.7 में पेश किए गए परिवर्तनों की एक प्रमुख विशेषता एक ही स्थान में काम करने वाले मेटाडेटा भंडारण का केंद्रीकरण है। .svnकार्यशील प्रति में प्रत्येक निर्देशिका में एक निर्देशिका के बजाय , सबवर्सन 1.7 की कार्यशील प्रतियों में कार्य .svnनिर्देशिका की जड़ में सिर्फ एक निर्देशिका है। इस निर्देशिका में (अन्य बातों के अलावा) एक SQLite- समर्थित डेटाबेस जिसमें उस कार्यशील प्रतिलिपि के सभी मेटाडेटा सबवर्सन की आवश्यकता है।


4
प्रदर्शन के लिए, find ... -print0 | xargs -0 egrep ...इसके बजाय का उपयोग करने का प्रयास करें find ... -exec grep ...( grepप्रत्येक फ़ाइल के लिए कांटा नहीं , लेकिन एक समय में फ़ाइलों का एक गुच्छा के लिए)। इस फ़ॉर्म का उपयोग करके आप खोज .svnके -pruneविकल्प का उपयोग किए बिना निर्देशिकाओं को भी prune कर सकते हैं, अर्थातfind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...
vladr

3
@Vlad: जहाँ तक मुझे पता है, का उपयोग कर -execके साथ +कांटा नहीं है grepप्रत्येक फ़ाइल के लिए है, जबकि इसके साथ का उपयोग कर ;करता है। उपयोग करना -execवास्तव में उपयोग करने से अधिक सही है xargs। कृपया ध्यान दें कि lsतर्क सूची खाली होने पर भी कुछ ऐसा करते हैं, जबकि chmodअपर्याप्त तर्क होने पर कमांड जैसी त्रुटि देता है। यह देखने के लिए कि मेरा क्या मतलब है, बस एक निर्देशिका में निम्नलिखित कमांड का प्रयास करें जिसमें कोई शेल स्क्रिप्ट नहीं है find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755:। इस एक के साथ तुलना करें find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+':।
सियु चिंग पोंग -आसुका केंजी-

2
@Vlad: इसके अलावा, grepबाहर आईएनजी .svnएक अच्छा विचार भी नहीं है। जबकि findफ़ाइल गुणों से निपटने के लिए विशेष है, grepनहीं है। आपके उदाहरण में, '.svn.txt' नाम की एक फ़ाइल भी आपके egrepआदेश द्वारा फ़िल्टर की जाएगी । हालाँकि आप अपने रेगेक्स को '^ / \ _ svn $' में संशोधित कर सकते हैं , फिर भी ऐसा करना अच्छा अभ्यास नहीं है। -pruneके विधेय findपूरी तरह से (फ़ाइल नाम, या सृजन टाइमस्टैम्प, या जो कुछ भी हालत आप आपूर्ति से) एक फ़ाइल छानने के लिए काम करता है। यह वैसे ही है जैसे कि आप एक बड़ी तलवार का उपयोग करके तिलचट्टे को मार सकते हैं, इसका मतलब यह नहीं है कि ऐसा करने का सुझाव दिया गया है :-)।
सियु चिंग पोंग -आसुका केंजी-

3
Git पर स्विच करने से यह समस्या (कई अन्य लोगों के बीच) निश्चित हो गई। केवल काम करने वाले कॉपी की जड़ पर एक .गित फ़ोल्डर बनाता है, एसवीएन की तरह हर फ़ोल्डर में नहीं। इसके अतिरिक्त, .it फ़ोल्डर में ऐसी साधारण फ़ाइलें नहीं होती हैं जो आपकी वास्तविक फ़ाइलों के साथ एक ही नाम से भ्रमित हों।
क्रॉनिक

3
2Dan मोल्डिंग: svn 1.7 केवल एक ही शीर्ष-स्तर .svn निर्देशिका बनाता है
ccpizza

जवाबों:


65

खोज के लिए, क्या मैं सुझाव दे सकता हूं कि आप ऐक को देखें ? यह एक सोर्स-कोड के बारे में पता है find, और जैसा कि ऊपर दिए गए सोर्स कोड रिपॉजिटरी जानकारी सहित कई फ़ाइल प्रकारों को स्वचालित रूप से अनदेखा करेगा।


3
मुझे ackबहुत पसंद है, लेकिन मैंने पाया है कि find -type f -name "*.[ch]" | xargs grepबड़े कोडबेस के साथ काम करने की तुलना में यह काफी धीमा है ।
जॉन लेडबेटर

63
जॉन, मैं ack का लेखक हूं, और यदि आप मुझे ack बनाम grep की गति की समस्याओं का विवरण दे सकते हैं, तो मैं इसकी सराहना करूंगा। वे सभी मामलों में पूरी तरह से तुलनीय हैं जो मैंने पाया है। या तो मुझे github.com/petdance/ack/issues पर बताएं या मुझे andy पर petdance.com पर ईमेल करें। Thansk।
एंडी लेस्टर

63
दोस्तों, यह एक टिप है, लेकिन निश्चित रूप से सवाल का जवाब नहीं! :)
dolzenko

8
नहीं है ackएक बेहतर रूप में बिल grep, नहीं एक स्रोत अवगत find? इसे बदलने के लिए इसका उपयोग करने के कुछ उदाहरणों से यह findवास्तविक उत्तर बन जाएगा।
मचिआकिग

3
यह उस सवाल का जवाब है जो वह नहीं जानता था कि वह पूछ रहा था। =)
फ्राँगी

293

सिर्फ क्यों नहीं

find . -not -iwholename '*.svn*'

-प्रोटेक में हर चीज की उपेक्षा की जाती है। पथ में कहीं भी।

तो आपके मामले में यह होगा

find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;

5
"-नोट" और "-होलेननेम" के लिए सुपर बड़ा +1। Ack अद्भुत है और मैं इसका उपयोग करता हूं, लेकिन ढूंढें / निष्पादित करें इसके उपयोग अभी भी हैं।
डेविड बॉलेन्स

9
एकमात्र प्रतिक्रिया जो वास्तव में मूल प्रश्न का उत्तर देती थी।
ब्रेंडन क्रॉफर्ड

14
मैं अपने तत्व से बाहर हूं और मुझे यकीन है कि मुझे इस टिप्पणी के लिए आलोचना मिलेगी, लेकिन जाहिरा तौर पर -नोट और -होलेननेम पॉसिक्स-अनुरूप नहीं हैं। मैंनें इस्तेमाल किया ! -होलेंनाम की जगह -नोट और -पैथ के स्थान पर और समान परिणाम मिले। मेरे मैन पेज (उबंटू 12.04) के अनुसार यह सिंटेक्स POSIX-compliant है।
जॉन

1
@whaley तुमने कहा था '*.svn*'पहले, लेकिन फिर से '*.svn'। कौन सा सही है? क्या दोनों काम करते हैं? मुझे लगता है कि यह शायद होना चाहिए '*.svn*'?
कीथ एम

1
@KeithM वास्तव में शानदार कैच। यह जवाब यहाँ वर्षों से बैठा है और मुझे नहीं लगता कि अब तक किसी ने पकड़ा था।
व्हेल

141

निम्नलिखित नुसार:

find . -path '*/.svn*' -prune -o -print

या, वैकल्पिक रूप से एक निर्देशिका के आधार पर और उपसर्ग नहीं:

find . -name .svn -a -type d -prune -o -print

14
@ कालेब: हाय। मैं सुझाव देता हूं find . -type d -name .svn -prune -o -printक्योंकि यह थोड़ा तेज है। POSIX मानक के अनुसार , अभिव्यक्तियों का मूल्यांकन एक-एक करके, निर्दिष्ट क्रम में किया जाता है। यदि पहली अभिव्यक्ति -aहै false, तो दूसरी अभिव्यक्ति का मूल्यांकन नहीं किया जाएगा (जिसे शॉर्ट-सर्किट और मूल्यांकन भी कहा जाता है )।
सियु चिंग पोंग -आसुका केंजी-

2
@ कालेब: फ़ाइल प्रकार की तुलना के रूप में (परीक्षण के बराबर है कि एक बिट में एक पूर्णांक सेट है) फ़ाइल नाम की तुलना करने से तेज है (एक स्ट्रिंग तुलना के बराबर है, जो ओ (एन) है), पहले से सैद्धांतिक रूप से अधिक कुशल है। हालाँकि, यह आमतौर पर महत्वहीन होता है सिवाय इसके अगर आपके पास बहुत बड़ी निर्देशिका का पेड़ है। -type d-name .svn
सियु चिंग पोंग -आसुका केंजी-

5
@ SiuChingPong-AsukaKenji- नहीं, केवल फ़ाइल नाम की तुलना में तेजी है क्योंकि -प्रत्येक को हर फाइल पर एक स्टेट (2) कॉल की आवश्यकता होती है। फ़ाइल नाम, हालांकि, रीडडीर (3) प्रतिक्रिया का हिस्सा है।
हरबैन

3
@JonathanHartley आप -printअंतिम अभिव्यक्ति के भाग को याद कर रहे हैं । find . -name .git -prune -o \( -type f -name LICENSE -print \)उम्मीद के मुताबिक कुछ काम करता है।
15 अक्टूबर को sschuberth

1
तुम दोनों .git ध्यान न दें और .svn और सिर्फ अन्य निर्देशिकाओं सूची बनाना चाहते हैं, find . -name .svn -prune -o -name .git -prune -o -type d -print। यह कुछ मिलीसेकंड तेजी -type dसे दोनों के सामने रख सकता है -name, लेकिन इसके अतिरिक्त टाइपिंग के लायक नहीं है।
जेपीगेट

34

अनदेखा करने के लिए .svn, .gitऔर अन्य छिपी निर्देशिका (डॉट के साथ शुरू), कोशिश करें:

find . -type f -not -path '*/\.*'

हालाँकि, यदि उपयोग करने का उद्देश्य findफ़ाइलों के भीतर खोज कर रहा है, तो आप इन आदेशों का उपयोग करने का प्रयास कर सकते हैं:

  • git grep - गिट रिपॉजिटरी के भीतर पैटर्न खोजने के लिए विशेष रूप से डिज़ाइन की गई कमांड।
  • ripgrep- जो डिफ़ॉल्ट रूप से छिपी हुई फाइलों और निर्दिष्ट फाइलों को अनदेखा करता है .gitignore

संबंधित: मुझे लिनक्स पर विशिष्ट पाठ वाली सभी फाइलें कैसे मिलेंगी?


सबसे अच्छा जवाब imo। दूसरे लोग उन चीजों को समझाने की कोशिश करते हैं जो आसान सवाल का जवाब नहीं देते हैं।
एंथनी

19

यहाँ मैं आपके मामले में क्या करूंगा:

find . -path .svn -prune -o -name messages.* -exec grep -Iw uint {} +

Emacs की rgrepअंतर्निहित कमांड .svnडायरेक्टरी को नजरअंदाज करती है , और कई और फाइलें जिन्हें आप शायद तब पसंद नहीं करते हैं जब ए find | grep। यह वह है जो इसे डिफ़ॉल्ट रूप से उपयोग करता है:

find . \( -path \*/SCCS -o -path \*/RCS -o -path \*/CVS -o -path \*/MCVS \
          -o -path \*/.svn -o -path \*/.git -o -path \*/.hg -o -path \*/.bzr \
          -o -path \*/_MTN -o -path \*/_darcs -o -path \*/\{arch\} \) \
     -prune -o \
       \( -name .\#\* -o -name \*.o -o -name \*\~ -o -name \*.bin -o -name \*.lbin \
          -o -name \*.so -o -name \*.a -o -name \*.ln -o -name \*.blg \
          -o -name \*.bbl -o -name \*.elc -o -name \*.lof -o -name \*.glo \
          -o -name \*.idx -o -name \*.lot -o -name \*.fmt -o -name \*.tfm \
          -o -name \*.class -o -name \*.fas -o -name \*.lib -o -name \*.mem \
          -o -name \*.x86f -o -name \*.sparcf -o -name \*.fasl -o -name \*.ufsl \
          -o -name \*.fsl -o -name \*.dxl -o -name \*.pfsl -o -name \*.dfsl \
          -o -name \*.p64fsl -o -name \*.d64fsl -o -name \*.dx64fsl -o -name \*.lo \
          -o -name \*.la -o -name \*.gmo -o -name \*.mo -o -name \*.toc \
          -o -name \*.aux -o -name \*.cp -o -name \*.fn -o -name \*.ky \
          -o -name \*.pg -o -name \*.tp -o -name \*.vr -o -name \*.cps \
          -o -name \*.fns -o -name \*.kys -o -name \*.pgs -o -name \*.tps \
          -o -name \*.vrs -o -name \*.pyc -o -name \*.pyo \) \
     -prune -o \
     -type f \( -name pattern \) -print0 \
     | xargs -0 -e grep -i -nH -e regex

यह अधिकांश संस्करण नियंत्रण प्रणालियों द्वारा बनाई गई निर्देशिकाओं की उपेक्षा करता है, साथ ही कई प्रोग्रामिंग भाषाओं के लिए उत्पन्न फाइलें भी। आप एक उपनाम है कि इस आदेश को आमंत्रित और बदल सकते findहैं और grepअपने विशिष्ट समस्याओं के लिए पैटर्न।


12

जीएनयू खोजते हैं

find .  ! -regex ".*[/]\.svn[/]?.*"

मैं एक पथ में निर्देशिका पथ को लोड करने के लिए PHP के लिए प्रोसेस कर रहा था। अन्य उत्तर उच्चतर (जो भी कारण के लिए) खोज में फ़ाइलों को फ़िल्टर नहीं किया (इसके बावजूद -type d) - इस उत्तर ने किया। +1
hollenbeck

11

मैं इस उद्देश्य के लिए grep का उपयोग करता हूं। इसे अपने ~ / .bashrc में डालें

export GREP_OPTIONS="--binary-files=without-match --color=auto --devices=skip --exclude-dir=CVS --exclude-dir=.libs --exclude-dir=.deps --exclude-dir=.svn"

ग्रीप स्वचालित रूप से आह्वान पर इन विकल्पों का उपयोग करता है


1
यह ध्यान देने योग्य है कि 'grep' ने केवल एक या दो साल पहले '--exclude-dir' विकल्प प्राप्त किया था। हाल के लिनक्स वितरणों में इसे शामिल किया गया है, लेकिन अगर मुझे सही से याद है कि मुझे OSX पर अपना खुद का grep संकलित करना था (या होमब्रे को ऐसा करने के लिए कहें)।
जोनाथन हार्टले

मैं इसका मामूली रूपांतर करता हूं। मेरा .bashrc एक बैश फ़ंक्शन 'grp' बनाता है, जिसे इस रूप में परिभाषित किया गया है GREP_OPTIONS=xxx grep "$@"। इसका अर्थ है कि GREP_OPTIONS चर केवल grep के उदाहरणों के लिए सेट किया गया है जिसे मैं 'grp' का उपयोग करके मैन्युअल रूप से चलाता हूं। इसका मतलब है कि मुझे कभी भी ऐसी स्थिति नहीं मिलती जहां मैं एक उपकरण चलाता हूं, और आंतरिक रूप से इसे grep कहते हैं, लेकिन उपकरण भ्रमित हो जाता है क्योंकि grep व्यवहार नहीं कर रहा है जैसा कि यह अपेक्षित था। इसके अलावा, मेरे पास एक दूसरा फ़ंक्शन 'ग्रैपी' है, जो 'ग्रैप' कहता है, लेकिन जोड़ता है --include=*.py, बस पायथन फाइलों को खोजने के लिए।
जोनाथन हार्टले

वास्तव में, प्रतिबिंब पर, यह मेरे रास्ते में अब GREP_OPTIONS का उपयोग करने की आवश्यकता नहीं है। अब मेरे पास सिर्फ एक शेल फंक्शन 'grp' है जो कॉल करता है grep --exclude=tags --exclude_dir=.git ...etc... "$@"। मुझे यह पसंद है कि यह 'एक' की तरह चलता है, लेकिन मैं इसके बारे में जागरूकता बनाए रखता हूं, और इस पर नियंत्रण रखता हूं कि यह क्या कर रहा है।
जोनाथन हार्टले

9

find . | grep -v \.svn


आपको रेग्जिप .में बचना होगा .svn
vladr

4
उपयोग - grep के साथ उपसर्ग-तार : | fgrep -v /.svn/या `| grep -F -v / .svn / ` बिल्कुल निर्देशिका को बाहर करने के लिए और उनके नाम के भाग के रूप में" .svn "के साथ फाइल नहीं।
स्टीफन पी।

8

क्यों आप अपने आदेश को grep के साथ पाइप नहीं करते हैं जो आसानी से समझ में आता है:

your find command| grep -v '\.svn'

आपको रेग्जिप .में बचना होगा .svn
vladr

@ शक की छाया के बिना येकलियन; यदि आप नहीं करते हैं, तो 'tsvn', '1svn', 'asvn' आदि निर्देशिकाओं को भी '' के बाद से अनदेखा किया जाएगा। ' एक regexp वाइल्डकार्ड है: 'किसी भी चरित्र से मेल खाता है'।
vladr

ठीक है, मैंने सोचा कि यह केवल -E और -G के मामले के लिए ही होगा। मैंने सिर्फ परीक्षण किया, मेरा बुरा। :(
येलियन

2
मुझे यह उत्तर पसंद है क्योंकि यह दूसरों की तुलना में वैचारिक रूप से सरल है। मैं 'खोज' उपयोग के लिए हास्यास्पद वाक्यविन्यास को याद नहीं कर सकता, लेकिन मैं निश्चित रूप से याद रख सकता हूं कि grep -v का उपयोग कैसे किया जाए क्योंकि यह बहुत सारी स्थितियों में उपयोग किया जाता है।
मैटिस्मिनम

8

नामक एक स्क्रिप्ट बनाएं ~/bin/svnfind:

#!/bin/bash
#
# Attempts to behave identically to a plain `find' command while ignoring .svn/
# directories.

OPTIONS=()
PATHS=()
EXPR=()

while [[ $1 =~ ^-[HLP]+ ]]; do
    OPTIONS+=("$1")
    shift
done

while [[ $# -gt 0 ]] && ! [[ $1 =~ '^[-(),!]' ]]; do
    PATHS+=("$1")
    shift
done

# If user's expression contains no action then we'll add the normally-implied
# `-print'.
ACTION=-print

while [[ $# -gt 0 ]]; do
    case "$1" in
       -delete|-exec|-execdir|-fls|-fprint|-fprint0|-fprintf|-ok|-print|-okdir|-print0|-printf|-prune|-quit|-ls)
            ACTION=;;
    esac

    EXPR+=("$1")
    shift
done

if [[ ${#EXPR} -eq 0 ]]; then
    EXPR=(-true)
fi

exec -a "$(basename "$0")" find "${OPTIONS[@]}" "${PATHS[@]}" -name .svn -type d -prune -o '(' "${EXPR[@]}" ')' $ACTION

यह स्क्रिप्ट एक सादे findकमांड के लिए समान रूप से व्यवहार करती है, लेकिन यह .svnनिर्देशिकाओं को बाहर निकालती है । अन्यथा व्यवहार समान है।

उदाहरण:

# svnfind -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;

यह स्क्रिप्ट काम नहीं करती जैसा कि मैं उम्मीद करूंगा। जब इसे "svnfind -type f" के साथ चलाया जाता है, तो यह svn-directory और svn-directory में फ़ाइलों को प्रिंट करता है
Ingo Fischer

@ifischer क्या आप echoखोज कमांड में एक जोड़ सकते हैं और मुझे बता सकते हैं कि किस कमांड को निष्पादित किया गया है? svnfind -type fमेरे Red Hat मशीन पर बहुत अच्छा काम करता है।
जॉन कुगेलमैन

ठीक है तो यह ओएस पर निर्भर लगता है। मैं डेबियन स्क्वीज़ (उबंटू पर ही) चला रहा हूं। मुझे समझ नहीं आ रहा है कि "ईको एड करें" से आपका क्या मतलब है?
इंगो फिशर

@ifischer अंतिम पंक्ति बदलें echo find "${OPTIONS[@]}"...ताकि यह वास्तव में इसे चलाने के बजाय खोज कमांड को प्रिंट करता है।
जॉन कुगेलमैन 15

ओके ने आखिरी लाइन को बदल दिया echo find ${OPTIONS[@]} ${PATHS[@]} -name .svn -type d -prune -o ( ${EXPR[@]} ) $ACTION, इससे मुझे निम्नलिखित आउटपुट मिले:find -type f -name .svn -type d -prune -o ( -true ) -print
इंगो फिशर

5

बस मैंने सोचा कि मैं कालेब और दूसरों के पदों (जो विकल्प , कमांड आदि का उपयोग विस्तृत करता हूं) के लिए एक सरल विकल्प जोड़ूंगा , जो विशेष रूप से आपके द्वारा प्रश्न में वर्णित उपयोग (और किसी अन्य समान उपयोग) पर लागू होता है:find -pruneackrepofind

  1. प्रदर्शन के लिए, आप हमेशा उपयोग करने के लिए प्रयास करना चाहिए find ... -exec grep ... +या (इस ओर इशारा करते हुए के लिए धन्यवाद केंजी) find ... | xargs egrep ...(पोर्टेबल) या find ... -print0 | xargs -0 egrep ..., (काम करता है रिक्त स्थान युक्त फ़ाइल नाम पर जीएनयू) के बजाय की find ... -exec grep ... \;

    find ... -exec ... +और find | xargsप्रपत्र कांटा नहीं है egrepएक समय में फाइलों का एक समूह के लिए प्रत्येक फ़ाइल के लिए, बल्कि, जिसका परिणाम बहुत तेजी से निष्पादन

  2. का उपयोग करते समय find | xargsप्रपत्र आप भी उपयोग कर सकते हैं grepआसानी से और जल्दी करने के लिए छँटाई .svn(या किसी भी निर्देशिका या नियमित अभिव्यक्ति), यानी find ... -print0 | grep -v '/\.svn' | xargs -0 egrep ...(उपयोगी आप कुछ जल्दी की जरूरत है और कैसे स्थापित करने के लिए याद करने के लिए परेशान नहीं किया जा सकता है जब findकी -pruneतर्क।)

    find | grep | xargsदृष्टिकोण जीएनयू के समान है findके -regexविकल्प (देखें ghostdog74की पोस्ट) है, लेकिन अधिक पोर्टेबल है (यह भी प्लेटफॉर्म जहां जीएनयू पर काम करेंगे findउपलब्ध नहीं है।)


1
@ व्लाद: कृपया ध्यान दें कि -execस्विच के लिए दो रूप हैं find: एक के साथ समाप्त हो रहा है ;और दूसरा समाप्त हो रहा है +। सभी मेल खाने वाली फ़ाइलों की एक सूची के साथ समाप्त होता +है {}। इसके अलावा, आपका रेगेक्स '/\.svn'फ़ाइल नामों से '.svn.txt'भी मेल खाता है। अधिक जानकारी के लिए कृपया मेरी टिप्पणियों को देखें।
सियु चिंग पोंग -आसुका केंजी-

2
@Vlad: यहाँfind उपयोगिता के लिए POSIX मानक है । कृपया -execहिस्सा देखिए :-)
सियु चिंग पोंग -आसुका केंजी-

4

एक स्रोत कोड रिपॉजिटरी में, मैं आमतौर पर केवल पाठ फ़ाइलों के लिए चीजें करना चाहता हूं।

सीवीएस, एसवीएन और जीआईटी रिपॉजिटरी फाइलों को छोड़कर, पहली पंक्ति सभी फाइलें हैं।

दूसरी पंक्ति सभी बाइनरी फ़ाइलों को बाहर करती है।

find . -not \( -name .svn -prune -o -name .git -prune -o -name CVS -prune \) -type f -print0 | \
xargs -0 file -n | grep -v binary | cut -d ":" -f1

3

मैं -not -path विकल्पों के साथ खोज का उपयोग करता हूं। मुझे प्रून के साथ अच्छी किस्मत नहीं मिली।

find .  -name "*.groovy" -not -path "./target/*" -print

लक्ष्य निर्देशिका पथ में नहीं groovy फ़ाइलों को मिलेगा।


3

इस समस्या को हल करने के लिए, आप बस इस शर्त का उपयोग कर सकते हैं:

find \( -name 'messages.*' ! -path "*/.svn/*" \) -exec grep -Iw uint {} +

आप इस तरह अधिक प्रतिबंध जोड़ सकते हैं:

find \( -name 'messages.*' ! -path "*/.svn/*" ! -path "*/CVS/*" \) -exec grep -Iw uint {} +

आप इसके बारे में अधिक जानकारी मैन पेज सेक्शन "ऑपरेटर्स" से प्राप्त कर सकते हैं: http://unixhelp.ed.ac.uk/CGI/man-cgi?find


3

ध्यान दें कि यदि आप करते हैं

find . -type f -name 'messages.*'

तब -printनिहित है जब पूरी अभिव्यक्ति ( -type f -name 'messages.*') सत्य है, क्योंकि कोई 'क्रिया' (जैसे -exec) नहीं है।

हालांकि, कुछ निर्देशिकाओं में उतरने से रोकने के लिए, आपको उन निर्देशिकाओं से मेल खाने वाली किसी भी चीज़ का उपयोग करना चाहिए और इसका अनुसरण करना चाहिए -prune(जिसका उद्देश्य निर्देशिकाओं में उतरना बंद करना है); इस तरह:

find . -type d -name '.svn' -prune

यह .svn निर्देशिकाओं के लिए ट्रू का मूल्यांकन करता है , और हम -o(या) द्वारा इसका अनुसरण करके बूलियन शॉर्ट-सर्किट का उपयोग कर सकते हैं , जिसके बाद -oकेवल पहले भाग के गलत होने पर चेक किए जाने के बाद क्या होता है, इसलिए एक .svn निर्देशिका नहीं है। दूसरे शब्दों में, निम्नलिखित:

find . -type d -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

केवल evalute चलेगा कि कौन से सही है -o, अर्थात् -name 'message.*' -exec grep -Iw uint {}, फ़ाइलें नहीं अंदर .svn निर्देशिका के लिए।

ध्यान दें कि क्योंकि .svnसंभवतः एक निर्देशिका है (और उदाहरण के लिए एक फ़ाइल नहीं), और इस मामले में निश्चित रूप से 'संदेश * नाम से मेल नहीं खा रहा है, आप शायद इसे छोड़ दें -type dऔर करें:

find . -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

अंत में, ध्यान दें कि यदि आप किसी क्रिया को छोड़ते हैं ( -execएक क्रिया है), तो इस तरह कहें:

find . -name '.svn' -prune -o -name 'message.*'

तब -printकार्रवाई निहित है, लेकिन -name '.svn' -prune -oभाग सहित WHOLE अभिव्यक्ति पर लागू होगी और इस तरह सभी .svn निर्देशिकाओं के साथ-साथ 'संदेश। *' फाइलें भी प्रिंट करें, जो कि शायद आप नहीं चाहते हैं। इसलिए आपको हमेशा -pruneइस तरह से उपयोग करते समय बूलियन अभिव्यक्ति के दाईं ओर एक 'एक्शन' का उपयोग करना चाहिए । और जब वह क्रिया प्रिंट हो रही हो तो आपको उसे स्पष्ट रूप से जोड़ना होगा, जैसे:

find . -name '.svn' -prune -o -name 'message.*' -print


2

प्रयास करें findrepo जो एक सरल आवरण के आसपास लगता है / ग्रेप और बहुत तेजी से पावती आप की तरह इस मामले में यह प्रयोग करेंगे:

findrepo uint 'messages.*'

2

wcfind एक आवरण आवरण स्क्रिप्ट है जिसका उपयोग मैं स्वचालित रूप से .svn निर्देशिकाओं को हटाने के लिए करता हूं।


1

यह मेरे लिए यूनिक्स प्रॉम्प्ट में काम करता है

Gfind। \ _- नोट -होलेननेम '* \ _। svn *' \ -type f -name 'संदेश। *' -exec grep -Iw uint {} +

ऊपर दिया गया निर्देश उन FILES को सूचीबद्ध करेगा जो .svn के साथ नहीं हैं और आपके द्वारा उल्लिखित grep करते हैं।


'gfind' एक टाइपो है? मेरे पास उबंटू 14.04 पर नहीं है।
जोनाथन हार्टले

आप 'मिल' का मतलब है, यह काफी काम नहीं करता है। यह फाइलों को भी फिल्टर कर देता है xxx.svnxxx। यह महत्वपूर्ण है - उदाहरण के लिए यदि आप svn के बजाय git का उपयोग कर रहे हैं, तो आप अक्सर फाइल में .ignignore (जो कि मेटाडेटा नहीं है, यह एक नियमित फ़ाइल है, जिसे रेपो में शामिल किया गया है) को खोजने से परिणामों में शामिल करना चाहते हैं।
जोनाथन हार्टले

1

मैं आमतौर पर grep के माध्यम से आउटपुट को एक बार हटाने के लिए निकाल देता हूं। अपने उपयोग में, यह बहुत धीमा नहीं है। विशिष्ट उदाहरण:

find -name 'messages.*' -exec grep -Iw uint {} + | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'

या

find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.