मैं एक फ़ाइल में इस या उस (2 चीजों) के लिए कैसे तैयार हो सकता हूं?


37

मेरे पास एक फ़ाइल है जिसमें "फिर" और "वहाँ" है।

हाँ मैं

$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some

और मैं कर सकता हूँ

$ grep "there " x.x
If there is no blob none some will be created

मैं एक ऑपरेशन में दोनों की खोज कैसे कर सकता हूं? मैंने कोशिश की

$ grep (then|there) x.x

-बश: अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि `('

तथा

grep "(then|there)" x.x
durrantm.../code
# (Nothing)

जवाबों:


53

आपको अभिव्यक्ति को उद्धरण चिह्नों में रखना होगा। आपको जो त्रुटि मिल रही है, (वह विशेष चरित्र के रूप में व्याख्या करने के परिणामस्वरूप है ।

साथ ही, आपको विस्तारित नियमित अभिव्यक्तियों का उपयोग करने के लिए grep को बताने की आवश्यकता है।

$ grep -E '(then|there)' x.x

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

$ grep '\(then\|there\)' x.x

इस मामले में समूहीकरण आवश्यक नहीं है।

$ grep 'then\|there' x.x

यह कुछ इस तरह के लिए आवश्यक होगा:

$ grep 'the\(n\|re\)' x.x

3
यह भी देखें grep $'then\nthere'और grep -e then -e there। ध्यान दें कि \|BREs में मानक नहीं है। बाकी है विशेष रूप से दोहरे उद्धरण चिह्नों के भीतर बैश व्यवहार करता है बैकस्लैश केवल पहले ", $, \ , `और न्यू लाइन।
स्टीफन चेजलस

1
का उद्देश्य क्या है x.x?
एलेक्स

7

बस एक त्वरित परिशिष्ट, अधिकांश जायके में एक कमांड होता है, जिसे egrep कहा जाता है, जो केवल -E के साथ grep होता है। मुझे व्यक्तिगत रूप से टाइप करना बहुत अच्छा लगता है

egrep "i(Pod|Pad|Phone)" access.log

Grep -E का उपयोग करने की तुलना में


2

(या कम से कम, मेरा) मैन पेज में REGULAR EXPRESSIONS के तहत दस्तावेजित सामग्री वास्तव में विस्तारित रेगेक्स के लिए है;

grep नियमित अभिव्यक्ति सिंटैक्स के तीन अलग-अलग संस्करणों को समझता है: "मूल," "विस्तारित" और "perl।" GNU grep में, बुनियादी और विस्तारित सिंटैक्स के बीच उपलब्ध कार्यक्षमता में कोई अंतर नहीं है। अन्य कार्यान्वयन में, बुनियादी नियमित अभिव्यक्ति कम शक्तिशाली हैं। निम्नलिखित विवरण विस्तारित नियमित अभिव्यक्तियों पर लागू होता है; बुनियादी नियमित अभिव्यक्तियों के लिए अंतर को बाद में संक्षेपित किया जाता है।

लेकिन grep डिफ़ॉल्ट रूप से उनका उपयोग नहीं करता है - आपको -Eस्विच की आवश्यकता है :

grep "(then|there)" x.x

क्योंकि (फिर से मैन पेज से):

मूल बनाम विस्तारित नियमित अभिव्यक्तियाँ

बुनियादी नियमित अभिव्यक्तियों में मेटा-वर्ण; +, {,।, (और;) अपना विशेष अर्थ खो देते हैं; इसके बजाय बैकस्लेस्ड संस्करण \ ?, +, {, \ |, (, और) का उपयोग करें।

तो आप भी उपयोग कर सकते हैं:

grep "then\|there" x.x

चूंकि कोष्ठक इस मामले में बहुत ही कम हैं।


0

बश की सुरुचिपूर्ण सादगी यह विशाल आदमी पृष्ठ में खो जाती है।

ऊपर दिए गए उत्कृष्ट समाधानों के अलावा, मैंने सोचा कि मैं आपको एक चेस शीट देने की कोशिश करूंगा कि कैसे पर्स और बयानों की व्याख्या की जाए । फिर इस रोडमैप का उपयोग करके मैं प्रश्नकर्ता द्वारा प्रस्तुत किए गए उदाहरणों को बेहतर तरीके से समझने में मदद करने के लिए पार्स करूंगा कि वे उद्देश्य के अनुसार काम क्यों नहीं करते हैं।


नोट: शेल स्क्रिप्ट लाइनों का उपयोग सीधे किया जाता है। टाइप की गई इनपुट-लाइनें पहले इतिहास-विस्तारित हैं।

प्रत्येक बैश लाइन को पहले टोकेनाइज्ड किया जाता है , या दूसरे शब्दों में कटा हुआ जिसे टोकन कहा जाता है । (ब्रेसिंग, टिल्ड, पैरामीटर, कमांड, अंकगणितीय, प्रक्रिया, शब्द विभाजन, और फ़ाइल नाम विस्तार सहित अन्य सभी विस्तार से पहले होता है।)

यहाँ एक टोकन का अर्थ है इन विशेष मेटा-वर्णों में से एक द्वारा अलग की गई इनपुट लाइन का एक भाग (सीमांकित):

space,  - White space...
tab, 
newline,

‘<’,    - Redirection & piping...
‘|’, 
‘>’
‘&’,    - And/Both < | > | >>  .or.  &<file descriptor>

‘;’,    - Command termination

‘(’,    - Subshell, closed by -     ‘)’

बैश कई अन्य विशेष पात्रों का उपयोग करता है लेकिन केवल ये 10 प्रारंभिक टोकन का उत्पादन करते हैं।

हालाँकि, क्योंकि इन मेटा-वर्णों को भी कभी-कभी एक टोकन के भीतर उपयोग किया जाना चाहिए, उनके विशेष अर्थ को दूर करने का एक तरीका होना चाहिए। इसे पलायन कहा जाता है। पलायन या तो एक या एक से अधिक वर्णों (जैसे 'xx..', "xx..") के एक स्ट्रिंग को उद्धृत करके किया जाता है , या किसी व्यक्ति के चरित्र को बैक-स्लैश के साथ जोड़कर (यानी \x) किया जाता है। (यह इस से थोड़ा अधिक जटिल है क्योंकि उद्धरणों को भी उद्धृत करने की आवश्यकता है, और क्योंकि दोहरे उद्धरण सब कुछ उद्धृत नहीं करते हैं, लेकिन यह सरलीकरण अभी के लिए करेगा।)

अन्य भाषाओं की तरह, टेक्स्ट के एक स्ट्रिंग को उद्धृत करने के विचार से बैश को भ्रमित न करें। बैश में उद्धरणों के बीच में क्या तार नहीं हैं, बल्कि मेटा-वर्णों के अनुभागों के अनुभाग बच गए हैं जिससे वे टोकन को नष्ट नहीं करते हैं।

ध्यान दें, 'और ", के बीच एक महत्वपूर्ण अंतर है , लेकिन यह एक और दिन के लिए है।

शेष अप्रकाशित मेटा-वर्ण तब टोकन विभाजक बन जाते हैं।

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

$ echo "x"'y'\g
xyg

$ echo "<"'|'\>
<|>

$ echo x\; echo y
x; echo y

पहले उदाहरण में एक अंतरिक्ष परिसीमा द्वारा निर्मित दो टोकन हैं: echoऔर xyz

इसी तरह 2 उदाहरण में।

तीसरा उदाहरण अर्धविराम बच रहा है में, तो वहाँ 4 एक अंतरिक्ष सीमांकक, द्वारा उत्पादित टोकन हैं echo, x;, echo, और y। पहला टोकन तब कमांड के रूप में चलाया जाता है, और इनपुट के रूप में अगले तीन टोकन लेता है। नोट 2 echoको निष्पादित नहीं किया गया है।


यह ध्यान रखना होगा बचने वर्णों के लिए बैश पहले दिखता है ( ', ", और \), और फिर नहीं छोड़ा जाएगा मेटा-चरित्र सीमांकक के लिए लग रहा है, इसी क्रम में।

यदि बच नहीं गए तो ये 10 विशेष वर्ण परिसीमनकर्ता के रूप में कार्य करते हैं token। उनमें से कुछ का अतिरिक्त अर्थ भी है, लेकिन सबसे पहले और सबसे महत्वपूर्ण, वे टोकन परिसीमनकर्ता हैं।


Grep क्या उम्मीद करता है

में ग्रेप ऊपर के उदाहरण इन टोकन की जरूरत है, , grep, ।stringfilename

सवाल का पहला प्रयास था:

$ grep (तब | वहाँ) xx

इस मामले में (, )और |नहीं छोड़ा जाएगा मेटा चरित्र है और इन्हें एक टोकन में इनपुट विभाजित करने के लिए की सेवा: grep, (, then, |, there, ), और x.x। ग्रेप देखना चाहता है grep, then|thereऔर x.x

प्रश्न का दूसरा प्रयास था:

grep "(तब | वहाँ)" xx

इस में tokenizes grep, (then|there), x.x। आप इसे देख सकते हैं अगर आप गूंज के लिए बाहर स्वैप करते हैं:

इको "(तब | वहाँ)" xx
(तब | वहाँ) xx

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