2011-12-15 13 views
46

यहाँ कैसे एक पार्टी में एक पैटर्न मिलान सभी फ़ाइलों की सूची दे सकता है:सूची फाइलें पैटर्न से मेल नहीं खाती हैं?

ls *.jar 

कैसे एक पैटर्न के पूरक सूची के लिए? यानी सभी फाइलें * .jar से मेल नहीं खाती हैं?

+0

शायद इसे रेगेक्स लेबल नहीं किया जाना चाहिए, * एक शेल-ग्लोबिंग वाइल्डकार्ड है, और यह नियमित अभिव्यक्ति * नहीं है, जो "शून्य या अधिक मात्रात्मक" है। – sweaver2112

+0

अच्छा बिंदु, हालांकि मैं सीख रहा हूं कि रेगेक्स का उपयोग करना संभवतः आपके द्वारा अपेक्षित मिलान प्राप्त करने के लिए बेहतर अभ्यास है। – paislee

उत्तर

38
ls | grep -v '\.jar$' 

उदाहरण के लिए।

+2

grep के लिए -v ध्वज क्या है? – paislee

+12

उलटा मैच। एक 'मैन grep' भी है। –

+0

आप दो फ़ाइल प्रकार कैसे कर सकते हैं? – Dan

2

एक समाधान ls -1|grep -v '\.jar$'

+0

['ls' के आउटपुट को पार्स न करें] (http://mywiki.wooledge.org/ParsingLs), धन्यवाद। –

+6

@gniourf_gniourf 'ls' पार्सिंग या 'गोटो' का उपयोग करने जैसे नियमों के बारे में धार्मिक नहीं है। कभी-कभी वे समाधान सर्वोत्तम काम करते हैं। –

+1

यह उन मामलों में से एक नहीं है; 'ढूंढो। -प्रिंट 0 | grep -z '\ .jar $' 'बेहतर काम करता है भले ही आप' --ignore' या Bash के विस्तारित ग्लोबिंग का उपयोग नहीं करना चाहते हैं। यह कहा गया है कि, अधिकांश लोग नियम को समझने के लिए एक संपूर्ण लेख नहीं पढ़ना चाहते हैं या उन्हें क्या करना चाहिए, और आप एक सरल स्पष्टीकरण और सिफारिश के अनुरूप फिट हो सकते हैं जैसे "यह किनारे के मामलों में काम नहीं करता है; एक टिप्पणी में 'find -print0' और' grep -z' के बजाय "का उपयोग करें। –

13

होगा find का एक उपयुक्त संस्करण के साथ, आप कुछ इस तरह कर सकता है, लेकिन यह एक छोटे से overkill है:

find . -maxdepth 1 ! -name '*.jar' 

find फ़ाइलें पाता है। . तर्क निर्दिष्ट करता है कि आप . से खोजना शुरू करना चाहते हैं, यानी वर्तमान निर्देशिका। -maxdepth 1 यह बताता है कि आप केवल एक स्तर गहरी खोजना चाहते हैं, यानी वर्तमान निर्देशिका। ! -name '*.jar' उन सभी फ़ाइलों को देखता है जो रीगेक्स *.jar से मेल नहीं खाते हैं।

जैसा कि मैंने कहा, यह इस एप्लिकेशन के लिए थोड़ा अधिक है, लेकिन यदि आप -maxdepth 1 हटाते हैं, तो आप फिर से सभी गैर-जार फ़ाइलों को खोज सकते हैं या आप आसानी से क्या कर सकते हैं।

27

अल्पज्ञात बैश विस्तार नियम:

ls !(*.jar) 
+2

बाश:!: घटना नहीं मिली। मुझे क्या ज़रुरत है? – paislee

+6

पहले कमांड लाइन पर 'shopt -s extglob' निष्पादित करने का प्रयास करें, फिर कमांड टाइप करें। दुकानों का उल्लेख करने के लिए –

58

उपयोग egrep शैली बढ़ाया पैटर्न मिलान।

ls !(*.jar) 

यह बैश-2.02-अल्फा 1 से शुरू हो रहा है। पहले

shopt -s extglob 

बैश-4.1-अल्फा के रूप में वहाँ डिफ़ॉल्ट रूप से इस सक्षम करने के लिए एक config विकल्प है के साथ सक्षम होना चाहिए।

+1

यय! –

+2

यह सही उत्तर है। सही के रूप में चिह्नित उत्तर सीधे खोल का उपयोग नहीं करता है, यह एक सहायक आदेश का उपयोग करता है। – dbn

+0

@dbw - यहां तक ​​कि अगर मुझे यह उत्तर अधिक पसंद है, तो स्वीकार्य उत्तर प्रश्न के लिए ठीक है। ओपी विशेष रूप से "सीधे खोल" का उपयोग करने के लिए नहीं पूछता है। –

14

POSIX गैर मिलान वाले ब्रैकेट एक्सप्रेशन को परिभाषित करता है, इसलिए हम शैल को हमारे लिए फ़ाइल नामों का विस्तार करने दे सकते हैं।

ls *[!j][!a][!r] 

हालांकि इसमें कुछ quirks है, लेकिन कम से कम यह किसी भी यूनिक्स खोल के साथ संगत है।

+0

+1। उपनाम के साथ संयुक्त थोड़ा बैश/पायथन/रूबी फ़ंक्शन, यानी। "lsnot" इसे आसानी से काम करने योग्य बना सकता है। – Nikkolasg

+0

यह तीन वर्णों से कम चीजों से मेल नहीं खाता है। –

1

और यदि आप एक से अधिक फ़ाइल एक्सटेंशन को बाहर करना चाहते हैं, तो उन्हें ls test/!(*.jar|*.bar) जैसे पाइप | से अलग करें। यह कोशिश करते हैं:

$ mkdir test 
$ touch test/1.jar test/1.bar test/1.foo 
$ ls test/!(*.jar|*.bar) 
test/1.foo 

अन्य उत्तर को देखते हुए आप पहली बार shopt -s extglob की जरूरत हो सकती।

+1

आप इसे '! (*। [Bj] ar)' के बजाय छोटा कर सकते हैं। –

संबंधित मुद्दे

 संबंधित मुद्दे