grep और डॉलर के चिह्न से बचना


31

मैं जानना चाहता हूं कि किन फाइलों में स्ट्रिंग है $Id$

grep \$Id\$  my_dir/mylist_of_files

0 घटनाएँ देता है।

मुझे पता चला कि मुझे उपयोग करना है

grep \$Id$ my_dir/mylist_of_files

तब मैं देखता हूं कि $Idआउटपुट में रंगीन है, अर्थात यह मिलान किया गया है।

मैं दूसरे से कैसे मेल कर सकता हूं $और \$Id\$काम क्यों नहीं करता।

इससे कोई फर्क नहीं पड़ता कि दूसरा $अंतिम चरित्र है या नहीं।

मैं grep2.9 का उपयोग करता हूं ।


अपना प्रश्न पोस्ट करने से पहले, मैंने google का उपयोग किया ...

मुझे एक उत्तर मिला

Test2 नामक फ़ाइल में $ (डॉलर का चिह्न) खोजने के लिए, दर्ज करें:

grep \\ $ test2

\\ (डबल बैकस्लैश) वर्ण शेल कमांड को एक $ $ (सिंगल बैकस्लैश, डॉलर साइन) पास करने के लिए मजबूर करने के लिए आवश्यक हैं। \ N (एकल बैकस्लैश) वर्ण, grep कमांड को निम्न चरित्र (इस उदाहरण में $) को एक अभिव्यक्ति चरित्र के बजाय शाब्दिक चरित्र के रूप में मानता है। बैकस्लैश जैसे भागने के पात्रों का उपयोग करने की आवश्यकता से बचने के लिए fgrep कमांड का उपयोग करें।

लेकिन मुझे समझ में नहीं आता कि क्यों grep \$Idकाम करता है और क्यों grep \\$Id\\$नहीं करता है।

मै थोड़ा अस्पष्ट हूँ...

जवाबों:


25

यहां 2 अलग-अलग मुद्दे हैं।

  1. grepबेसिक रेगुलर एक्सप्रेशंस (BRE) का उपयोग करता है , और $अभिव्यक्ति के अंत में केवल BRE का एक विशेष चरित्र है। इस का परिणाम यह है की 2 उदाहरणों है $में $Id$बराबर नहीं हैं। पहला एक सामान्य चरित्र है और दूसरा एक लंगर है जो पंक्ति के अंत से मेल खाता है। दूसरे $मैच को शाब्दिक बनाने के लिए $आपको बैकस्लैश से बचना होगा, अर्थात $Id\$। पहले बचना $भी काम करता है: \$Id\$और मुझे यह पसंद है क्योंकि यह अधिक सुसंगत दिखता है। works

  2. यहाँ काम पर दो पूरी तरह से असंबंधित पलायन / उद्धृत तंत्र हैं: शेल उद्धरण और रेगेक्स बैकस्लैश उद्धरण। समस्या कई पात्रों की है जो नियमित अभिव्यक्ति का उपयोग शेल के लिए विशेष रूप से करते हैं, और उस शीर्ष पर रेगेक्स एस्केप कैरेक्टर, बैकस्लैश भी एक शेल क्विंग कैरेक्टर है। यही कारण है कि आप अक्सर डबल बैकस्लैश को शामिल करते हुए गड़बड़ देखते हैं, लेकिन मैं नियमित अभिव्यक्ति को उद्धृत करते हुए शेल के लिए बैकस्लैश का उपयोग करने की अनुशंसा नहीं करता हूं क्योंकि यह बहुत पठनीय नहीं है।

    इसके बजाय, ऐसा करने का सबसे सरल तरीका यह है कि पहले अपने पूरे रेगेक्स को सिंगल कोट्स के अंदर रखें 'regex'। एकल उद्धरण शेल के पास उद्धृत करने का सबसे मजबूत रूप है, इसलिए जब तक आपके रेगेक्स में एकल उद्धरण शामिल नहीं होते हैं, आपको अब शेल उद्धरण के बारे में चिंता करने की ज़रूरत नहीं है और शुद्ध BRE सिंटैक्स पर ध्यान केंद्रित कर सकते हैं।

तो, अपने मूल उदाहरण पर वापस लागू करते हुए, आइए \$Id\$एकल उद्धरणों के अंदर सही रेगेक्स ( ) को फेंकें । निम्नलिखित को वह करना चाहिए जो आप चाहते हैं:

grep '\$Id\$' my_dir/my_file

कारण \$Id\$काम नहीं करता है क्योंकि शेल उद्धरण हटाने के बाद (शेल उद्धरण कहने का अधिक सही तरीका) लागू किया जाता है, जो रेक्सक्स grepदेखता है वह है $Id$। जैसा कि (1.) में बताया गया है, यह रेगेक्स $Idकेवल एक पंक्ति के अंत में शाब्दिक रूप से मेल खाता है क्योंकि पहला $शाब्दिक है जबकि दूसरा एक विशेष लंगर चरित्र है।

¹ ध्यान दें कि यदि आप कभी भी एक्सटेंडेड रेगुलर एक्सप्रेशंस (ERE) पर जाते हैं, उदाहरण के लिए यदि आपने उपयोग egrep(या grep -E) करने का निर्णय लिया है , तो $चरित्र हमेशा विशेष होता है। ईआरई में $Id$कभी भी कुछ भी मेल नहीं खाएगा क्योंकि आपके पास एक पंक्ति के अंत के बाद वर्ण नहीं हो सकते हैं , इसलिए \$Id\$जाने का एकमात्र तरीका होगा।


3
नियमित अभिव्यक्ति के रूप में इसके 1 पैरामीटर की व्याख्या करने से बचने के लिए, आप यह भी कर सकते हैं grep -F '$Id$'
jfg956

मेरे खोल में (4.3.42 मार) grep '$Id\$' ...और grep \$Id\\$ ...काम
नीतस

2
और अगर यह एक makefile में एक कमांड है, आप भी पलायन करना होगा $एक पूर्ववर्ती के साथ $: grep '$$Id\$$'stackoverflow.com/a/2382810/2097284
केमिली गौडेय्यून

-2

$Id$किसी फ़ाइल में खोजने के लिए : आप उपयोग कर सकते हैं:grep '\$id*' filename


2
यह किसी भी चीज़ से मेल खाएगा $id, इसलिए $ideaउदाहरण के लिए, न कि केवल $id$
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.