पुनरावर्ती ग्लोब?


80

मैं कुछ इस तरह लिखना चाहता हूं:

$ ls **.py

सभी .py फ़ाइल नाम प्राप्त करने के लिए, पुन: एक निर्देशिका पदानुक्रम चलना।

यदि खोजने के लिए .py फाइलें हैं, तो भी शेल (bash) यह आउटपुट देता है:

ls: cannot access **.py: No such file or directory

किसी भी तरह से मुझे क्या चाहिए?

संपादित करें: मैं यह निर्दिष्ट करना चाहूंगा कि मुझे विशिष्ट मामले में कोई दिलचस्पी नहीं है ls, लेकिन सवाल ग्लोब सिंटैक्स के बारे में है।

जवाबों:


98

बैश में पुनरावर्ती ग्लब्स करने के लिए, आपको globstarबैश संस्करण 4 या उच्चतर से सुविधा की आवश्यकता है ।

बैश मैनपेज से:

globstar
    If set, the pattern ** used in a pathname expansion context will
    match all files and zero or more directories and subdirectories.
    If the pattern is followed by a /, only directories and
    subdirectories match.

अपने उदाहरण पैटर्न के लिए:

shopt -s globstar
ls **/*.py

2
मैं भी सक्षम करने की सलाह देता हूंnullglob
ग्लेन जैकमैन

6
@glennjackman लेकिन सक्षम करने से पहले nullglob, मैं चेतावनी के बाद पढ़ने की जोरदार सलाह दूंगा ।
सर्ज स्ट्रोबंड्ट

2
^ चेतावनियां यहां आ गई हैं
usandfriends

1
बैश 3.2 के साथ, wc -l {**,.}/*.pyठीक काम करता है
राफेल

@ राफेल I ने रिलीज़ नोटों की दोहरी जाँच की और यह निश्चित रूप से कहता है कि इसे 4.0 में पेश किया गया था। शायद आपने वितरण को इसके लिए एक पैच बैकपोर्ट किया है? IIRC आरएचईएल 5 ने कुछ सुविधाओं का समर्थन किया था। नोट के अलावा, यह 4 साल की रिलीज के बाद से 9 साल हो गया है ...
जोर्डन

10
find . -name '*.py'

** एक एकल * से अधिक कुछ भी नहीं करता है, दोनों वर्तमान निर्देशिका में काम करते हैं


दिलचस्प। हालांकि, मैं स्वयं द्वारा ग्लोब सिंटैक्स पर अधिक ध्यान केंद्रित कर रहा हूं, क्योंकि मुझे इसे कॉन्फ़िगरेशन फ़ाइल (निर्देश शामिल करें) में उपयोग करना है। मुझे फ़ाइलों की सूची की आवश्यकता नहीं है।
पाओलो

2
@ डॉग ओ'नील, यह अब सच नहीं है। बैश ने अब उस zsh फीचर को कॉपी कर लिया है (हालाँकि इसने ksh93 के समान एक सिंटैक्स अपनाया है और ksh की तरह, zsh के ग्लॉबिंग क्वालिफायर का समर्थन नहीं करता है जो अभी तक इसकी उपयोगिता को सीमित करता है)
Stéphane Chazelas

बहुत सी चीजें हैं जो आप के साथ कर सकते हैं findयदि आपके पास बैश नहीं है 4. उदाहरण: yourcommand `find . -name '*.py'`(बैकटिक्स पर ध्यान दें); find . -name '*.py' -exec yourcommand {} \;
मंगल

5

चूंकि बैश 4 (भी zsh सहित) एक नया ग्लोबिंग विकल्प ( globstar) जोड़ा गया है जो **सेट होने पर पैटर्न को अलग तरीके से व्यवहार करता है ।

यह वाइल्डकार्ड पैटर्न से मेल खा रहा है और मेल खाने वाली फाइल और डायरेक्टरी के नामों को मिलान करके वाइल्डकार्ड पैटर्न को कमांड आइटम से बदल देता है।

आम तौर पर जब आप उपयोग करते हैं **, तो यह समान काम करता है *, लेकिन यह सभी निर्देशिकाओं को पुनरावर्ती (लूप की तरह) पुन: बनाता है।

यह देखने के लिए कि क्या यह सक्षम है, इसे shopt globstar(स्क्रिप्टिंग में, उपयोग करके shopt -q globstar) देखें।

उदाहरण **.pyकेवल वर्तमान निर्देशिका के लिए काम करेगा, क्योंकि यह उन निर्देशिकाओं की सूची नहीं देता है, जो पुनरावृत्ति हो सकती हैं, इसलिए आपको कई निर्देशिका-स्तरीय वाइल्डकार्ड का उपयोग करने की आवश्यकता है **/*.py, इसलिए यह अधिक गहराई तक जा सकता है।

कृपया SO कुछ सिंटैक्स परीक्षणों पर खोजें जो मैंने सभी फ़ाइलों को पुनरावर्ती खोजने के लिए किया था।

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