क्यों "grep *" काम नहीं कर रहा है?


0

इन दिनों linux सीखने पर, मैंने पाया कि कुछ ने मुझे ux भ्रमित किया

$ cat abcd
line One
line Two
line Three
$ cat abcd | grep *
$ _                       //nothing greped
$ cat abcd | grep ""
line One
line Two
line Three
$ cat abcd | grep "*"
$ _                       //nothing greped

"_" सिर्फ कर्सर है, गलती मत करो :)

यह कौन समझाएगा? धन्यवाद

linux  grep 

क्या है _? मेरी मशीन पर, यह, पैदावार _: command not found
.रोब

इसके अलावा, आपको क्या उम्मीद थी कि आप cat abcd | grep *प्रिंट करेंगे?
ΔRob

यह कर्सर है, बस यहां ब्लिंक नहीं करें :)

जवाबों:


2

ग्लोब *का विस्तार शेल द्वारा वर्तमान निर्देशिका में सभी (नॉन-डॉट) फाइलों की एक अल्फाबेटिक सूची में किया गया है। तर्क grepएक खोज अभिव्यक्ति और फ़ाइलों की एक सूची है। तो grep *पहले फ़ाइल नाम का उपयोग खोज अभिव्यक्ति के रूप में होता है। आप दूसरी फ़ाइलों में पहली फ़ाइल के नाम (एक नियमित अभिव्यक्ति के रूप में) की तलाश कर रहे हैं।

यदि आप किसी भी स्पष्ट फ़ाइल नाम की आपूर्ति नहीं करते हैं, तो ग्रेप केवल मानक इनपुट खोजता है। देख:

echo moo | grep . /etc/issue
Handmade Linux for OS/X v 0.001

संयोग से, *एक वैध नियमित अभिव्यक्ति नहीं है। जैसा कि आपने खोजा है, एक खाली खोज अभिव्यक्ति सभी इनपुट लाइनों से मेल खाती है। एक नियमित अभिव्यक्ति जो सभी गैर-रिक्त इनपुट लाइनों से मेल खाती है .; regex में, डॉट एक मेटाचैकर है जो एक वर्ण, नई पंक्ति को छोड़कर किसी भी वर्ण से मेल खाता है। क्लेन स्टार एक प्रत्यय ऑपरेटर है जो पिछली नियमित अभिव्यक्ति के शून्य या अधिक दोहराव की अनुमति देता है, इसलिए आप अक्सर .*"कुछ भी" के लिए रेगेक्स देखते हैं , लेकिन इस संदर्भ में, यह बेमानी है, क्योंकि आप पहले से ही कुछ भी मेल नहीं खा रहे हैं। खाली खोज स्ट्रिंग के साथ।

अंत में, यह catएक फ़ाइल के लिए खराब रूप माना जाता है । इसके बजाय cat file | grep ""आप एक प्रक्रिया को सहेजते हैं और शायद कुछ सीधे फाइल को पढ़ने के द्वारा खराब हो grepजाते हैं;grep "" file


1

grep *ऐसा करने के लिए "ग्लोबिंग" वर्तमान निर्देशिका में फ़ाइलों के खिलाफ विस्तार हो रहा है।

मैं वास्तव में भविष्यवाणी नहीं कर सकता कि क्या होगा, लेकिन *निश्चित रूप से abcdफ़ाइल नाम से मेल खाएगा । तो आप abcdफ़ाइल में "abcd" खोज सकते हैं । या आप दूसरी फ़ाइलों में (lexographically) पहली फ़ाइल के नाम की खोज कर सकते हैं।

यदि वर्तमान निर्देशिका खाली थी, तो आप खोज करना समाप्त कर देंगे *। लेकिन यह भी काम नहीं करेगा क्योंकि पहला कमांड लाइन तर्क एक रेगेक्स है, और "*" एक वैध रेगेक्स नहीं है।

ग्लोबिंग को रोकने के लिए, इसे लिखें:

$ cat abcd | grep "*"

... लेकिन यह ऊपर दिए गए कारण के लिए कोई मतलब नहीं है।

शाब्दिक "*" वर्ण की खोज करने के लिए:

$ cat abcd | grep "\\*"

यह जानने का सबसे अच्छा तरीका है कि क्या होने की कोशिश की जाएगीecho *

हाँ ... लेकिन >> मैं << ऐसा नहीं कर सकते। इसलिए मेरे लिए यह भविष्यवाणी करना कठिन है कि क्या होगा :-)
स्टीफन सी

1

grepकमांड लाइन तर्क देखने से पहले , उस तर्क को शेल द्वारा पार्स किया गया है। शेल के लिए, *"वर्तमान निर्देशिका में सभी गैर-डॉट फाइलें" के लिए एक वाइल्डकार्ड है। चूंकि शेल पहले तर्क को संभालता है, आपकी रेखा इस में बदल जाती है:

cat abcd | grep abcd otherfile zfile

(यह मानते हुए कि वे तीन फाइलें आपकी वर्तमान निर्देशिका में रहती हैं)। यह वही है जो grepइसके तर्कों को देखने के लिए मिलता है, लेकिन यह वह नहीं है जो आप चाहते हैं।

इसके बजाय, आप grepउद्धरण चिह्नों के लिए पैटर्न रख सकते हैं , ताकि यह शेल द्वारा संसाधित न हो :

cat abcd | grep "*"

यह बेहतर है, लेकिन फिर भी आप क्या चाहते हैं: grepनियमित अभिव्यक्ति का उपयोग करता है, शेल-स्टाइल वाइल्डकार्डिंग नहीं। तारांकन के लिए grep, का अर्थ है "पिछले चरित्र की 0..n पुनरावृत्ति" - एक ऐसा चरित्र जिसे आपने निर्दिष्ट नहीं किया था। नजदीक पर बिना सिगार के।

यदि आप "कोई भी" पैटर्न चाहते हैं, तो आप "एक मनमाना चरित्र के 0..n दोहराव" की तलाश कर रहे हैं । उत्तरार्द्ध को '.'नियमित अभिव्यक्तियों में अवधि ( ) द्वारा दर्शाया गया है :

cat abcd | grep ".*"

वही जो तुम चाह रहे थे।

संपादित करें: अन्य मामला अधिक आसानी से समझाया गया है। साथ grep ""आप एक के लिए देख रहे खाली स्ट्रिंग है, जो किसी भी स्ट्रिंग में सबस्ट्रिंग के रूप में मौजूद है।


सिवाय catबेकार है और रेगेक्स बेकार है। partmaps.org/era/unix/award.html
tripleee

@tripleee: मैंने इस "पुरस्कार" को एसओ जैसी साइटों पर उल्लास के साथ उछाला है। मुझे नहीं लगता कि यह उचित है। हम यहां उत्पादन कोड के बारे में बात नहीं कर रहे हैं; catइस उदाहरण में "जब मैं कुछ मनमाने ढंग से मानक इनपुट grepping रहा हूँ" के लिए एक सामान्य स्टैंड में है। एक उत्तर को समझना आसान है जब यह पूरी तरह से सिर्फ "अनावश्यक" से बचने के अपने लेट कौशल को दिखाने के लिए एक सार उदाहरण को किसी और चीज़ में नहीं बदलता है cat- लेकिन मूल कोड के साथ चिपक जाता है और कुछ ट्विस्ट दिखाता है वास्तव में प्रश्न के मूल से संबंधित हैं।
DevSolar

मैं इसे गुमराह के रूप में देखता हूं; एक उत्तर जो स्पर्शरेखा और कैविएट को समझाने में विफल रहता है, वह एक उत्तर की तुलना में कम मूल्यवान है जो यह सुनिश्चित करने की कोशिश करता है कि मूल दृष्टिकोण ध्वनि है। यह उतना बुरा नहीं है जितना कि "कोशिश chmod 0777 *" जवाब आप कभी-कभी देखते हैं, लेकिन "लक्षणों को ठीक करना" दृष्टिकोण में एक समानता है।
ट्रिपलआई

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

महान व्याख्या! लेकिन अभी भी एक सवाल है: क्यों और कैसे $ cat abcd | grep ""काम करता है? मेरा मतलब है कि यह सिर्फ एक खाली स्ट्रिंग है, इसे क्या बनाते हैं ( "") से अलग है "*"- जबकि "*"कुछ भी नहीं मिला?

0

बैश हमेशा निर्देशिका में फ़ाइल के लिए वाइल्डकार्ड प्लेसहोल्डर के रूप में * पार्स करता है। आपकी आज्ञा में बैश इसे मानते हैं

cat abcd | grep abcd file1 file2 ...

इसलिए यह केवल खाली आउटपुट दिखाता है क्योंकि यह वह नहीं है जो आप खोज रहे हैं


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