`[!]` (कोष्ठक में विस्मयादिबोधक चिह्न) बैश में वाइल्डकार्ड


10

मैं ग्लोबिंग पैटर्न और वाइल्डकार्ड के साथ आया हूं और मेरे लिए विशेष रुचि है [!]

इस निर्माण के लिए समान है [!], सिवाय इसके बजाय कोष्ठक के अंदर कोई भी वर्ण मिलान से, यह किसी भी चरित्र की भरपाई करेंगे जब तक यह के बीच सूचीबद्ध नहीं है, निर्माण [और ]

rm myfile [!192]

ऊपर मेरा मानना ​​है कि किसी भी / सभी फाइलों को छोड़कर कोई भी / सभी फाइलें हटा दें, जिनके नाम पर 192 हैं।

हालाँकि, एक फ़ाइल एक्सटेंशन के साथ और विशेष रूप से कई स्थितियों में इसके उचित उपयोग के बारे में मैं चिंतित हूं।

ऐसी स्थिति में उचित वाक्यविन्यास क्या होगा?

rm myfile [!.gif .csv. mp3] 

या

rm myfile [!.gif !.csv !.mp3]

मेरी चिंता यह है कि अवधि गलत हो सकती है, और इसलिए किसी भी फाइल के साथ .(जो कि उनमें से कोई भी निश्चित रूप से होगा?) तब हेरफेर किया जाएगा, जब मैं विशिष्ट फ़ाइलों के हेरफेर का कारण बन रहा हूं।

इस निर्माण के लिए समान है [ ], सिवाय इसके बजाय कोष्ठक के अंदर कोई भी वर्ण मिलान से, यह किसी भी चरित्र की भरपाई करेंगे जब तक यह के बीच सूचीबद्ध नहीं है, निर्माण [और ]

( http://www.tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm से उद्धृत )

अभी; मुझे पता चलता है कि तब एक विलक्षण !पर्याप्त है, और उसके बाद के सभी मान सीमा के भीतर समाहित हैं।


5
एक सामान्य टिप के रूप में, का उपयोग करें ls my-patternया echo my-commandजाँच करें कि क्या rm
ग्लोबिंग

यह भी याद रखें कि कई, यदि अधिकांश नहीं हैं, तो फाइलों में एक्सटेंशन नहीं हैं। लिनक्स सिस्टम पर एक्सटेंशन आमतौर पर अप्रासंगिक हैं और अधिकांश प्रोग्रामों द्वारा फ़ाइल प्रकार को परिभाषित करने के लिए उपयोग नहीं किया जाता है।
टेराडॉन

2
ध्यान दें कि आपका पहला उद्धरण गलत है, अब यह मूल रूप से ऐसा ही प्रतीत होता [!]है लेकिन ऐसा नहीं है[!]
ilkachachu

2
यह ध्यान देने योग्य है कि इस संदर्भ में ^जैसा सटीक अर्थ !है, इसलिए बिल्कुल वैसा ही [^a]शामिल नहीं है: यदि पहला अक्षर निम्नलिखित है [a! या ^ तब संलग्न किसी भी वर्ण का मिलान नहीं होता है। ( )a[!a]man bash
मिठाई

3
rm myfile [!192]निकाल देंगे myfile, साथ ही किसी भी एकल चरित्र फ़ाइल का नाम नहीं 1, 9, या 2
केविन

जवाबों:


16

उद्धृत man 7 glob:

An  expression  "[!...]"  matches  a single character, namely any character
that is not matched by the expression obtained by removing the first '!' from it.
(Thus, "[!]a-]" matches any single character except ']', 'a' and '-'.)

यहाँ एकल चरित्र भाग पर जोर , []बैश पैटर्न मिलान में पूरे तार के लिए इस्तेमाल नहीं किया जा सकता है।


bashकी ब्रेस विस्तार , तार मिलान करने के लिए इस्तेमाल किया जा सकता लेकिन वहाँ कोई रास्ता नहीं है (मैं के बारे में पता) उन्हें नकारना है। उदाहरण के लिए

1.{gif,csv,mp3}

तक विस्तारित है

1.gif 1.csv 1.mp3

कोई फर्क नहीं पड़ता कि ये फाइलें मौजूद हैं।


जैसा कि wchargin ने बताया कि shoptविस्तारित पैटर्न मिलान ऑपरेटरों को सक्षम करने के लिए इस्तेमाल किया जा सकता है, उनमें से एक है !()। दौड़ने के बाद shopt -s extglob, उदा

1.!(gif|csv|mp3)

तक विस्तारित है

1.jpg 1.bmp 1.png

यदि वे फ़ाइलें वर्तमान निर्देशिका में मौजूद हैं। अधिक पढ़ने के लिए man bash(खंड विस्तार / पथनाम विस्तार) और पथनाम विस्तार (ग्लोबिंग)


आप जो करने की कोशिश कर रहे हैं find, उसके लिए मैं हमेशा उपयोग करूंगा , जो कि निम्न प्रकार से नकार और बहुत कुछ प्रदान करता है:

find . -maxdepth 1 -type f ! -name "*.gif" -a ! -name "*.csv" -a ! -name "*.mp3"

यह सिर्फ निष्कर्षों को सूचीबद्ध करता है, यदि आप उन्हें हटाना चाहते हैं तो केवल -deleteविकल्प को कमांड के अंत में जोड़ें । हमेशा की कार्रवाई को हटाने के साथ: हमेशा पहले ध्यान से जांच करें

findद्वारा समझाया गया एक टन उपयोगी विकल्प प्रदान करता है man find


1
ध्यान दें कि यह findकमांड पुनरावर्ती है ( संपादित करें: जैसा कि यह मूल रूप से दिखाया गया था - मैं इस टिप्पणी को अतिरिक्त प्रासंगिक लेकिन गैर-जानकारी के लिए रख सकता हूं जो यह बताती है)। केवल वर्तमान निर्देशिका में रहने वाली फ़ाइलों को खोजने के लिए, लेकिन इसके उपनिर्देशिका भी नहीं - और इस प्रकार केवल उन फ़ाइलों को हटा दें यदि -deleteकार्रवाई जोड़ दी जाती है - आप इसके -maxdepth 1तुरंत बाद जोड़ सकते हैं find .। यह इसे ग्लोबिंग के प्रभाव के अनुरूप लाएगा, क्योंकि जब तक globstarशेल विकल्प चालू नहीं होता है और **इसका उपयोग नहीं किया जाता है तब तक ग्लब्स बैश में नॉनक्रिसिव होते हैं । प्रश्न में दिखाया गया ग्लोब सभी गोले में गैर-उपयोगी है।
एलियाह कगन

2
"कोई रास्ता नहीं (मैं के बारे में पता) उन्हें नकारना है" -साथ shopt -s extglob, तो आप उपयोग कर सकते हैं echo 1.!(gif|csv|mp3), जो सभी प्रिंट 1.extजहां extनहीं है gif, csvया mp3। ("प्रतिमान मिलान" उपधारा देखें man bash)
wchargin

10

मुझे लगता है कि आपने कोष्ठक के उपयोग को गलत समझा। किसी एक पात्र से [abc]मेल खाता है , या । एक चरित्र से मेल खाता है , या नहीं है । तो कमांडabc[!abc] abc

rm myfile [192]

हटाएंगे myfileऔर फ़ाइलें 1, 9और 2क्योंकि आपके पास माईफाइल और ब्रैकेट के बीच एक स्थान है। इसके विपरीत, आज्ञा

rm myfile[192]

फ़ाइलों को हटा देगा myfile1, myfile9और myfile2


सच। उपयोग करने के लिए बेहतर है find
pLumo

वास्तव में [] का उपयोग एक सीमा के लिए किया जाता है, [!] एक एकल चरित्र
आयरनहॉलन

1
@ इरोनलन, वे दोनों एक सीमा या पात्रों की एक सूची लेते हैं। यह सिर्फ इतना है कि दूसरा एक नकार है।
ilkachachu

7

ब्रैकेट [ ]एक चरित्र वर्ग को दर्शाते हैं। उनके अंदर कोई भी एक वर्ण दिए गए पद से मेल खा सकता है। इसलिए

file[192]

तीन संभावित नामों से मेल खाता है:

file1
file2
file9

यह मेल नहीं खाता है file192, क्योंकि यह केवल एक के बाद के चरित्र से संबंधित है file

हम कोष्ठक में श्रेणियों का उपयोग भी कर सकते हैं। [0-9]दी गई स्थिति में किसी एक अंक से मेल खाता है। दो अंकों के लिए, हमें चाहिए [0-9][0-9]। किसी कैपिटल लेटर के बाद के अंक के लिए, हम उपयोग कर सकते हैं [0-9][A-Z]...

! नकारात्मकता को इंगित करता है।

file[!192]

के बाद किसी भी एक वर्ण है कि फ़ाइलों से मेल खाएगी fileको छोड़कर 1या 9या 2। उदाहरण के लिए यह की भरपाई कर देंगे file7और filesऔर file%(और कई अन्य) लेकिन नहीं file192 , क्योंकि वह दो अतिरिक्त कैरेक्टर हैं।

आपके उपयोग के मामले में, मैं findइसके बजाय का उपयोग करने का सुझाव देता हूं [!]। इसका एक notसंचालक है।

यह भी पुनरावर्ती है , जिसका अर्थ है कि यह डिफ़ॉल्ट रूप से सभी उपनिर्देशिकाओं में जाता है। -maxdepth 1यदि आप चाहते हैं, तो आप इसे वर्तमान निर्देशिका तक सीमित कर सकते हैं। शेल वाइल्डकार्ड (ग्लोबिंग) गैर-पुनरावर्ती (हालांकि पुनरावर्ती ग्लोबिंग को **सक्षम किया जा सकता है)।

यह मानते हुए कि आप सहानुभूति को हटाने से बचना नहीं चाहते हैं, हम -type dकिसी भी निर्देशिका को हटाने से बचने के लिए नकारात्मक परीक्षणों में जोड़ सकते हैं । उस सुझाव के लिए एलिया कगन को धन्यवाद।

find /path -maxdepth 1 -not \( -type d -or -iname "*.gif" -or -iname "*.csv" -or -iname "*.mp3" \)

यदि आप देखते हैं कि आप क्या चाहते हैं, तो आप फिर से कमांड चला सकते हैं -delete

find /path -maxdepth 1  -not \( -type d -or -iname "*.gif" -or -iname "*.csv" -or -iname "*.mp3" \) -delete

2
और मुझे लगता है कि आप एक साथ कई रेंज भी कर सकते हैं। उदाहरण के लिए, हेक्साडेसिमल अंक हो सकता है[0-9a-fA-F]
विल्सन

@Zanna, हाँ! मैं वास्तव में खोज का उपयोग कर रहा था :) एहसास नहीं था कि यह "नहीं" ऑपरेटर है :)
आयरनहॉलन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.