`find -name` पैटर्न जो कई पैटर्न से मेल खाता है


334

मैं कमांड के साथ एक निर्देशिका में सभी अजगर और HTML फ़ाइलों की एक सूची प्राप्त करने की कोशिश कर रहा था find Documents -name "*.{py,html}"

इसके बाद मैन पेज आया:

पैटर्न के भीतर ब्रेसिज़ ('{}') को विशेष नहीं माना जाता है (अर्थात, खोजें। -नाम 'फू {1,2}' एक फ़ाइल से मेल खाता है जिसका नाम फू {1,2} है, न कि फ़ाइलें foo1 और foo2।

चूंकि यह एक पाइप-चेन का हिस्सा है, इसलिए मैं यह निर्दिष्ट करने में सक्षम होना चाहूंगा कि यह रनटाइम के दौरान किन एक्सटेंशनों से मेल खाता है (कोई हार्डकोडिंग नहीं)। अगर पाते हैं कि यह नहीं कर सकते हैं, एक पर्ल वन-लाइनर (या समान) ठीक होगा।

संपादित करें: मैं जिस उत्तर के साथ आया था उसमें सभी प्रकार की बकवास शामिल है, और थोड़ा लंबा भी है, इसलिए मैंने इसे मूल खुजली के जवाब के रूप में पोस्ट किया था जिसे मैं खरोंचने की कोशिश कर रहा था। यदि आपके पास बेहतर समाधान हैं तो बेझिझक हैक करें।



अक्सर अनदेखी और अप्रयुक्त उपयोगिता भी होती है locate, भले ही यह कहा जाता है कि आंतरिक अद्यतन अप-टू-डेट नहीं हो सकता है। लेकिन यह तेज है।
माइकल

मैं इस प्रश्न को ऑफ-टॉपिक के रूप में बंद करने के लिए मतदान कर रहा हूं क्योंकि यह यूनिक्स और लिनक्स पर है
Dan Dascalescu

जवाबों:


480

उपयोग करें -o, जिसका अर्थ है "या":

find Documents \( -name "*.py" -o -name "*.html" \)

आपको उस कमांड लाइन को प्रोग्रामेटिक रूप से बनाने की आवश्यकता होगी, जो इतना आसान नहीं है।

क्या आप bash (या विंडोज पर Cygwin) का उपयोग कर रहे हैं? यदि आप हैं, तो आपको यह करने में सक्षम होना चाहिए:

ls **/*.py **/*.html

जो प्रोग्रामेटिक रूप से बनाना आसान हो सकता है।


3
मैं zsh का उपयोग कर रहा हूं, जो कि एक सामान्य नियम के रूप में, सभी बशीज़ का समर्थन करता है, साथ ही अधिक भी।
Xiong Chiamiov

12
ज़र्श **पुनरावर्ती खोज के लिए समर्थन करता है ; बैश केवल 4.0 और उसके बाद के संस्करणों में इसका समर्थन करता है, और केवल साथ shopt -s globstar
अपरिपक्व

2
आपके पास कितने-कितने आर्ग हो सकते हैं? मैं एक संभावित बड़ी सूची मिल गया है .gcda (कवरेज डेटा) फ़ाइलों का निर्माण करने के लिए
जैस्पर ब्लूज़

40
-nameयदि आप उपयोग कर रहे हैं, तो आपको ब्रैकेट के साथ दो एस को घेरना होगा -exec। जैसेfind Documents \( -name "*.py" -o -name "*.html" \) -exec file {} \;
आर्टब्रिस्टल

2
@artbristol टिप्पणी बहुत प्रासंगिक है यदि, उदाहरण के लिए, आप -print0रिक्त स्थान के साथ फ़ाइल नाम को संभालने के लिए जोड़ रहे हैं ।
नीमरोड

63

खोज के कुछ संस्करण, ज्यादातर लिनक्स सिस्टम पर, संभवतः दूसरों के आधार पर -regex और -regextype विकल्प, जो रेगेक्स से मेल खाने वाले नामों वाली फ़ाइलों को ढूँढता है।

उदाहरण के लिए

find . -regextype posix-egrep -regex ".*\.(py|html)$" 

उपरोक्त उदाहरण में चाल करना चाहिए। हालाँकि यह एक मानक POSIX फंक्शन नहीं है और यह कार्यान्वयन पर निर्भर है।


1
इंटरस्टिंग लेकिन अन्य उत्तरों की तुलना में अधिक जटिल
m1k3y3

12
सरल: find . -regex ".*\.\(py\|html\)$"यह काम करता है क्योंकि Emacs- शैली के नियमित अभिव्यक्तियों के लिए डिफॉल्ट पाते हैं, जो थोड़े अलग होते हैं, इसलिए आपको रीग्ज़ेक्ट को निर्दिष्ट करने की आवश्यकता नहीं है।
27

2
यदि आपके पास बहुत से भाव हैं -regextype posix-egrep, तो आसान है (अन्यथा आपको बहुत सारे पात्रों से बचना होगा)। यह एक विंडोज़-डिस्ट्रिब्यूशन ज़िप बनाने वाली डिस्ट-हुक बिल्डिंग के लिए मैंने जो खोजा है, वह है (फाइलों को बदलने के लिए और इन-फाइल उन्हें डॉस- find -regextype posix-egrep -regex ".*(\.([chyl]|def|cpy|cob|conf|cfg)|(README|ChangeLog|AUTHORS|ABOUT-NLS|NEWS|THANKS|TODO|COPYING.*))$" -exec sed -i -e 's/\r*$/\r/' {} \;
एओल में

32

आप प्रोग्रामेटिक रूप से अधिक -nameक्लॉस जोड़ सकते हैं, इसके द्वारा अलग किए गए -or:

find Documents \( -name "*.py" -or -name "*.html" \)

या, इसके बजाय एक साधारण लूप के लिए जाएं:

for F in Documents/*.{py,html}; do ...something with each '$F'... ; done

@ user2284570: फिर या तो कोई *.pyफाइल नहीं है या आपके पास कुछ विषम संस्करण है find। ऊपर सूचीबद्ध कमांड ठीक काम करती है।
Stephan202

नहीं, मैं उपयोग कर रहा हूं -iname*.pyयदि यह अंतिम स्थिति में लिखता है (तो iname *.htmlयह पहली अभिव्यक्ति है) केवल फाइलें लौटाता है । मैं डेबियन पर कमांड का उपयोग करता हूं।
user2284570

क्या आप उद्धरण का उपयोग कर रहे हैं? यह बहुत महत्वपूर्ण है।
Stephan202

1
यह एक या एक -o है?
स्टीफन

1
@StephaneEybert: या तो ठीक है, लेकिन केवल बाद वाला POSIX अनुरूप है (मैन पेज के अनुसार)।
Stephan202

16

यह linux पर सभी .c या .cpp फाइलें ढूंढेगा

$ find . -name "*.c" -o -name "*.cpp"

जब तक आप कुछ अतिरिक्त मॉड्स नहीं कर रहे हैं तब तक आपको बची हुई कोष्ठक की आवश्यकता नहीं है। यहां मैन पेज से वे कह रहे हैं कि यदि पैटर्न मेल खाता है, तो इसे प्रिंट करें। शायद वे मुद्रण को नियंत्रित करने की कोशिश कर रहे हैं। इस स्थिति में -प्रिंट एक सशर्त के रूप में कार्य करता है और एक "AND'd" सशर्त बन जाता है। यह किसी भी .c फाइलों को प्रिंट होने से रोकेगा।

$ find .  -name "*.c" -o -name "*.cpp"  -print

लेकिन अगर आप मूल उत्तर पसंद करते हैं तो आप प्रिंटिंग को नियंत्रित कर सकते हैं। यह सभी .c फाइलों को भी ढूंढेगा।

$ find . \( -name "*.c" -o -name "*.cpp" \) -print

सभी c / c ++ स्रोत फ़ाइलों के लिए एक अंतिम उदाहरण

$ find . \( -name "*.c" -o -name "*.cpp"  -o -name "*.h" -o -name "*.hpp" \) -print

11

मेरी भी ऐसी ही जरूरत थी। यह मेरे लिए काम किया:

find ../../ \( -iname 'tmp' -o -iname 'vendor' \) -prune -o \( -iname '*.*rb' -o -iname '*.rjs' \) -print

3
उत्तम। लेकिन मुझे यह थोड़ा अजीब लगता है कि यह ()
पीड्रोफुरला के

मैं उन फ़ाइलों को खोजना चाहता था जो * .c * .c * .cpp या * .cc से मेल खाती हों, केवल दो-नाम के पैटर्न के साथ मुझे parens की जरूरत नहीं थी, लेकिन तीन -name पैटर्न के साथ दो -o पैटर्न के साथ जुड़ने के find -name "*.cpp" -o -name "*.c" -o -name "*.cc" -print0लिए मुझे parens की एक जोड़ी का उपयोग करना था। दूसरे या ऑपरेटर का समूह। find -name "*.cpp" -o \( -name "*.c" -o -name "*.cc" \) -print0यह हो सकता है कि -प्रिंट0, जो हमेशा "सच" हो, तर्क को प्रभावित करता है।
कार्डिफ स्पेस मैन

5

मेरा डिफ़ॉल्ट रहा है:

find -type f | egrep -i "*.java|*.css|*.cs|*.sql"

कम प्रक्रिया intencive जैसा findब्रेंडन लौंग और Stephan202 एट अल द्वारा निष्पादन .:

find Documents \( -name "*.py" -or -name "*.html" \)


3
यह egrepregexp का एक सही उपयोग नहीं है , बल्कि, आप एक शेल ग्लोब है जहाँ एक regexp का उपयोग किया जाना चाहिए। (इसके अलावा, विशिष्ट findउपयोग है: find {directory} [options...] [action]जहां, निहितार्थ के आधार पर, directoryडिफ़ॉल्ट हो सकता है ., और actionचूक हो सकती है -print, लेकिन मैं स्पष्ट हो जाऊंगा।) इसलिए, इसके बजाय, कुछ इस तरह का उपयोग करें: find . -type f -print | egrep -i '\.java$|\.css$|\.cs$|\.sql$' लेकिन साथ ही, वास्तव में तेजी से विकल्प के रूप में find, एक भी हो सकता है। locateएक समान तरीके से प्रयास करें (यद्यपि जरूरी नहीं कि यह किसी फ़ाइल सूची के लिए आंतरिक db
michael

2
#! /bin/bash
filetypes="*.py *.xml"
for type in $filetypes
do
find Documents -name "$type"
done

सरल लेकिन काम करता है :)


1

मुझे कुछ फाइलों को छोड़कर बच्चे के डायर में सभी फाइलों को हटाने की आवश्यकता थी। निम्नलिखित ने मेरे लिए काम किया (तीन पैटर्न निर्दिष्ट):

find . -depth -type f -not -name *.itp -and -not -name *ane.gro -and -not -name *.top -exec rm '{}' +

1

\(\)नाम के पैटर्न के साथ पैटर्न के भीतर ब्रेस की आवश्यकता होती हैor

find Documents -type f \( -name "*.py" -or -name "*.html" \)

जबकि andऑपरेटर के साथ नाम पैटर्न के लिए यह आवश्यक नहीं है

find Documents -type f ! -name "*.py" -and ! -name "*.html" 

0

यह AIX कोर्न शेल पर काम करता है।

find *.cbl *.dms -prune -type f -mtime -1

इस की तलाश में है *.cblया *.dmsजो मौजूदा निर्देशिका में केवल 1 दिन पुराने हैं,, उप-निर्देशिका लंघन।


0
find MyDir -iname "*.[j][p][g]"
+
find MyDir -iname "*.[b][m][p]"
=
find MyDir -iname "*.[jb][pm][gp]"

2
ध्यान दें कि उत्तरार्द्ध foo.jmg से मेल खाएगा, लेकिन दोनों शीर्ष वसीयत में से कोई भी नहीं।
ताम्र .hat

0

व्हाट अबाउट

ls {*.py,*.html}

यह उनके फ़ाइलनाम में .py या .html के साथ समाप्त होने वाली सभी फ़ाइलों को सूचीबद्ध करता है

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