फ़ाइल नाम में शेल विस्तार (ए | बी)?


9

क्या orउदाहरण के लिए फ़ाइल पढ़ते समय शेल में किसी विकल्प का विस्तार करना संभव है ।

उदाहरण के लिए, इसका मतलब यह है कि, एक फ़ाइल में A या B से मेल करना grepसिंटैक्स का समर्थन करता है (A|B)

इसी तरह, अगर मेरे पास ये फाइलें हैं:

file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

मैं कर सकता cat file{1..5}.txtथा bash, क्योंकि यह सीमा का विस्तार करता है। वहाँ सिर्फ फ़ाइलों के एक जोड़े के लिए यह करने के लिए एक समान तरीका है?

जैसे cat file(1|5).txtऔर केवल उन 2 को प्रिंट करें?

जवाबों:


16

किसी अंक से मिलान करने के लिए मानक फ़ाइल नाम ग्लोबिंग पैटर्न है [0-9]। यह एकल अंक से मेल खाता है:

cat file[0-9].txt

इनमें से केवल दो का चयन करने के लिए:

cat file[25].txt

9 से बड़ी संख्या के लिए, ब्रेस विस्तार उपयोगी होगा (लेकिन ग्लोबिंग पैटर्न और ब्रेस एक्सपोज़र के बीच अंतर के लिए नीचे नोट देखें):

cat file{25..60}.txt

फिर से, ब्रेस विस्तार व्यक्तिगत संख्या के लिए भी अनुमति देता है:

cat file{12,45,900,xyz}.txt

(ध्यान दें कि ऊपर के उदाहरण में, ब्रेस विस्तार में एक अंकगणितीय लूप शामिल नहीं है, लेकिन बस प्रदान किए गए तार के आधार पर नाम उत्पन्न करता है)।

में bash, के साथ extglobखोल विकल्प सक्षम ( shopt -s extglob), निम्नलिखित भी काम:

cat file@(12|45|490|foo).txt

@(...)पैटर्न शामिल में से किसी एक से मेल खाएगी |-delimited पैटर्न।


ग्लोबिंग पैटर्न के रूप में [...]और @(...)ब्रेस विस्तार के बीच का अंतर यह है कि एक ब्रेस विस्तार कमांड लाइन पर उत्पन्न होता है और वर्तमान निर्देशिका में किसी भी मौजूदा नामों से मेल नहीं खा सकता है। एक फ़ाइल नाम ग्लोबिंग पैटर्न नामों से मेल खाएगा, लेकिन यदि सभी संभावित नाम मौजूद नहीं हैं, तो शेल शिकायत नहीं करेगा। यदि कोई मिलान नाम मौजूद नहीं है, तो पैटर्न अप्रतिबंधित रहेगा, जब तक कि nullglobशेल विकल्प सेट नहीं किया जाता है, जिस स्थिति में पैटर्न हटा दिया जाता है।

उदाहरण:

touch file1

ls file[0-9]

यहां, केवल फ़ाइल प्रविष्टि file1दिखाई जाएगी।

के साथ ls file{0..9}, lsनहीं खोजने के बारे में शिकायत करेंगे file0, file2आदि।

निम्नलिखित उदाहरण में, पहला कमांड केवल मौजूदा नामों को स्पर्श करेगा जो दिए गए पैटर्न से मेल खाते हैं, जबकि दूसरी पंक्ति उन फ़ाइलों को बनाएगी जो पहले से मौजूद नहीं हैं:

touch file[0-9]

touch file{0..9}

@ मैं माफी चाहता हूँ, लेकिन यह एक पैटर्न नहीं है जो उदाहरण के लिए मेल खाएगा file45.txt। ब्रैकेट अभिव्यक्ति [...]नियमित अभिव्यक्ति की तरह ही काम करती है, लेकिन "नहीं" कहने !के ^लिए उपयोग करती है । एक [...]पैटर्न हमेशा एक ही चरित्र से मेल खाएगा।
Kusalananda

तुम सही हो! BTW, मेरे {1,2}POSIX के अनुरूप नहीं है ... आज कुछ नई चीजें सीखीं!
13

2
तथ्य यह है कि ब्रेस एक्सपैंशन को वास्तविक फ़ाइलों से मेल खाने की ज़रूरत नहीं है, यदि आप इसका उपयोग कर रहे हैं (उदाहरण के लिए), तो इसे पास करने के लिए पैटर्न उत्पन्न करने के लिए grep, URL को पास करने के लिए जनरेट करें curl, और इसी तरह ... लेकिन यह भी भ्रामक हो सकता है। जो लोग ग्लब्स के साथ काम करने के आदी हैं।
केविन

@ केविन सही। ब्रेस विस्तार को फाइलनाम के बारे में होने की आवश्यकता नहीं है।
Kusalananda

7

उपयोग करने के लिए वाक्यविन्यास है file{1,2}जो मूल्यांकन करेगा file1और file2

$ ls
$ touch file{1,2,3,4,5,6,7,8,9}
$ ls
file1  file2  file3  file4  file5  file6  file7  file8  file9

जैसा कि Inian नीचे बताया गया है ... touch file{1..9}इस उदाहरण के मामले में यह करना आसान होगा ...

$ ls
$ touch file{1..9}
$ ls
file1  file2  file3  file4  file5  file6  file7  file8  file9

आप कई भावों का भी उपयोग कर सकते हैं, जैसे:

$ ls
$ touch file{1..9}{a..z}
$ ls
file1a file1b file1c
[...]
file9x file9y file9z

हां, ऊपर 234 ( 9बार 26) फाइलें बनाएगा ।


1
यह file{1,2} सिंटैक्स फ़ाइलों का नाम बदलने के लिए भी सुविधाजनक है:mv some_very_long_filename.txt{,.bak}
एरिक ड्यूमिनिल

6

हाँ आप bashशेल में ब्रेस विस्तार का उपयोग कर सकते हैं । केवल कुछ फ़ाइलों के लिए file{1..2}या बस के रूप में करते हैंfile{1,2}

या अगर आप कुछ मामलों में फ़ाइलों के न होने से चिंतित हैं, तो बस एक साधारण लूप करें,

for file in file{1..4}.txt; do
    [ -f "$file" ] || continue
    echo "$file" # Do other actions on file here
done

या अगर सिर्फ कॉन्फेटिंग फाइलों पर आपका एकमात्र ऑपरेशन है और अगर आप अनिश्चित हैं कि कौन सी फाइलें किसी भी समय मौजूद नहीं हो सकती हैं, तो बस catउन्हें और त्रुटियों को दबा दें। /dev/nullयदि फ़ाइल उपलब्ध नहीं है, तो मानक त्रुटि को फिर से निर्देशित करना त्रुटियों को दबा देगा।

cat file{1,5}.txt 2>/dev/null

या ग्लोब एक्सप्रेशन का उपयोग करें file[15]जो कि फाइल नहीं मिलने पर त्रुटियों के बारे में शिकायत नहीं करता है।

cat file[15].txt

2
नहीं, फ़ाइलों के नहीं होने के बारे में कोई चिंता नहीं, मैं सिर्फ संख्यात्मक रूप से गिने जाने वाली 2 फाइलों की सामग्री को दिखाना चाहता था, लेकिन यह लगातार नहीं है, इसलिए file{1,5}अल्पविराम वाक्यविन्यास मुझे याद आ रहा था!
जो हेले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.