क्या grep सही / गलत हो सकता है या वैकल्पिक तरीके हैं


130

इस स्क्रिप्ट के एक भाग के रूप में, मुझे यह जाँचने में सक्षम होना चाहिए कि पहले दिए गए तर्क फ़ाइल के पहले शब्द से मेल खाते हैं या नहीं। यदि ऐसा होता है, तो त्रुटि संदेश के साथ बाहर निकलें; यदि ऐसा नहीं होता है, तो फ़ाइल में तर्कों को जोड़ दें। मैं समझता हूं कि विवरण कैसे लिखना है if, लेकिन grepस्क्रिप्ट के भीतर कैसे उपयोग किया जाए । मैं समझता हूं कि grepऐसा कुछ दिखाई देगा

grep ^$1 schemas.txt

मुझे ऐसा लगता है कि इसे बनाने की तुलना में यह बहुत आसान होना चाहिए।

मुझे ifकथन पर "बहुत सारे तर्क" की त्रुटि मिल रही है । मुझे बीच में जगह से छुटकारा मिल गया grep -qऔर फिर एक त्रुटि बाइनरी ऑपरेटर से अपेक्षा की गई।

if [ grep -q ^$1 schemas.txt ]
then
        echo "Schema already exists. Please try again"
        exit 1
else
        echo "$@" >> schemas.txt
fi

1
खोना [... ]और यह काम करेगा। : आप शायद अपने पैटर्न उद्धृत करने के लिए चाहते हैं हालांकिif grep -q "^$1" schemas.txt; then …
derobert

बैश के "ग्रुप कमांड" फीचर का उपयोग करके एक लाइन सॉल्यूशन: stackoverflow.com/questions/6550484/…
ट्रेवर बोयड स्मिथ

जवाबों:


186

grepएक अलग निकास कोड देता है अगर यह कुछ पाया (शून्य) बनाम अगर यह कुछ भी नहीं मिला है (गैर-शून्य)। एक ifबयान में, एक शून्य निकास कोड "सच" के लिए मैप किया जाता है और एक गैर-शून्य निकास कोड को झूठे में मैप किया जाता है। इसके अलावा, grep का -qमिलान किए गए पाठ को आउटपुट नहीं करने का तर्क है (लेकिन केवल निकास स्थिति कोड लौटाएं)

तो, आप इस तरह से grep का उपयोग कर सकते हैं:

if grep -q PATTERN file.txt; then
    echo found
else
    echo not found
fi

एक त्वरित टिप्पणी के रूप में, जब आप कुछ ऐसा करते हैं if [ -z "$var" ]…, तो यह पता चलता है कि [वास्तव में एक कमांड है जिसे आप चला रहे हैं, जैसे कि grep। मेरे सिस्टम पर, यह है /usr/bin/[। (ठीक है, तकनीकी रूप से, आपके शेल में संभवतः यह अंतर्निहित है, लेकिन यह एक अनुकूलन है। यह ऐसा व्यवहार करता है जैसे कि यह एक आदेश था)। यह उसी तरह से काम करता [है, सच के लिए शून्य निकास कोड देता है, झूठे के लिए गैर-शून्य निकास कोड। ( समापन के अलावा भी testयही बात है )[]


यदि कथन को कोष्ठक की आवश्यकता क्यों नहीं है? मैं इसके बिना काम कर रहा हूं, लेकिन समझ नहीं आता कि क्यों। क्या मैं अभी भी इसे कोष्ठक के बिना घोंसला बना सकता हूं?
लॉरेन

@ लॉरेन क्या आपने त्वरित नोट को याद किया? [अगर सिंटैक्स का हिस्सा नहीं है, तो यह (वैचारिक रूप से) एक कमांड है जिसे आप चला रहे हैं, जैसे grep
derobert

2
@ लॉरेन आप [के अंदर grep का उपयोग नहीं करते हैं, आप एक या दूसरे का उपयोग करते हैं, इस बात पर निर्भर करता है कि आप किस शर्त पर जांचना चाहते हैं। (आप किसी भी कमांड का उपयोग अगर, btw, अगर सिर्फ एक्ज़िट कोड की जाँच कर सकते हैं।) ... ठीक है, मुझे लगता है कि आप शायद अंदर grep का उपयोग करने के लिए एक कारण के साथ आ सकते हैं, लेकिन यह एक काफी जटिल स्क्रिप्ट होगी, और इसकी सामान्य बात नहीं है।
derobert

3
FYI करें, चलाएं ls -l /usr/bin/\[और man [देखें कि [यह किसी अन्य की तरह एक कार्यक्रम है, यह सिर्फ एक सिंटैक्टिक तत्व की तरह दिखता है - इसे स्पष्ट और समझने में आसान बनाना चाहिए। (सुविधा के लिए, [एक बिल्ट-इन बाश, डैश और अन्य भी है - लेकिन यह अभी भी एक कमांड है)। type -all [बैश में भी प्रयास करें ।
कैस

1
@AlexanderCska यदि आप चाहते हैं कि मिलान रेखाओं को प्रिंट करने के लिए grep (जैसे, उन्हें कहीं पाइप करने के लिए), तो छोड़ दें -q, यह विकल्प बताता है कि grep शांत होगा (मिलान लाइनों को प्रिंट नहीं करें)।
derobert

47

एक और सरल तरीका उपयोग करना है grep -c

वह आउटपुट (निकास कोड के रूप में वापस नहीं), पैटर्न से मेल खाने वाली रेखाओं की संख्या, इसलिए यदि कोई मेल नहीं है या 1 या उससे अधिक है तो एक मैच है।

इसलिए, यदि आप जांचना चाहते हैं कि पैटर्न 3 या अधिक बार मेल खाता है, तो आप ऐसा करेंगे:

if [ "$(grep -c "^$1" schemas.txt)" -ge 3 ]; then
  ...

17
अधिक सटीक रूप से, यह 1 आउटपुट करेगा यदि केवल एक बार मिला। आउटपुट 1 की परवाह किए बिना पाया मैच की राशि का उपयोग करें grep -cim1
मैनेटवर्क

इस विधि का उपयोग grep त्रुटि और grep '0 बार पाया गया पैटर्न' के बीच अंतर करने के लिए भी किया जा सकता है। (हालांकि सटीक के साथ नहीं यदि कथन का उपयोग किया गया है, मुझे लगता है कि एक चर की आवश्यकता है)
इवान बेन्न

3

मुझे पता है कि मुझे इसके लिए देर हो रही है, लेकिन मुझे यह छोटा संस्करण पसंद है:

grep -q ^$1 schemas.txt && echo "Schema already exists. Please try again" || echo "$@" >> schemas.txt

0

अगर हम किसी फ़ाइल के पहले शब्द को पकड़ना चाहते हैं तो हमें -zwgrep को जोड़ना होगा

if grep -qzw "^$1" file
then 
   ... 
else 
   ... 
fi

बिना -zहमें एक लाइन का पहला शब्द मिलता है। बिना -wहमें आंशिक शब्द मिले।


-2

यदि आप इसे वर्ग कोष्ठक के साथ उपयोग करना चाहते हैं, तो आप नीचे निष्पादित कर सकते हैं

if [ `grep -q PATTERN file.txt` ]; then
    echo found
else
    echo not found

यह लॉजिक सभी कमांड्स के लिए काम करता है, बस अपने कमांड्स को बैकटिक के अंदर रखें (टैब के ऊपर का बटन या Esc बटन के नीचे या 1 बटन के बाईं ओर)


1
आपको उद्धृत करने की आवश्यकता होगी `grep -q PATTERN file.txt`, अन्यथा विभाजन + ग्लोब ऑपरेटर लागू किया जाता है और इससे किसी भी आउटपुट के लिए समस्या पैदा होगी जिसमें वर्ण $IFSया वाइल्डकार्ड वर्ण शामिल हैं। अधिक आम तौर पर, [ "`cmd`" ]यह सच है अगर cmdstdout पर कम से कम एक गैर-खाली लाइन आउटपुट करता है (संभावित समस्याओं के साथ अगर यह एनयूएल बाइट्स आउटपुट करता है)। इसका मतलब है कि शेल को पूरे आउटपुट को मेमोरी में स्टोर करना होगा और इसके खत्म होने का इंतजार करना होगा। if cmd | grep -q .इसके बजाय का उपयोग उस संबंध में बेहतर हो सकता है।
स्टीफन चेजलस

इस आदेश का कोई मतलब नहीं होगा। -qस्विच का उद्देश्य आउटपुट को दबाना है grep । आप कह रहे हैं: फ़ाइल में PATTERN के लिए जाँच करें। किसी भी आउटपुट को दबाएं, फिर उस स्थिति को सेट करें, जिसके अनुसार PATTERN पाया गया था। फिर, वापसी की स्थिति को अनदेखा करें, कमांड आउटपुट (जिसे हम खाली होने के लिए मजबूर किया गया था) लें, शब्द विभाजन और फ़ाइल ग्लोब विस्तार (जिसके परिणामस्वरूप कोई तर्क नहीं है) लागू करें, फिर ठीक एक तर्क के साथ [(उर्फ test) कमांड चलाएं - अर्थात् , और ]फिर, क्योंकि यह एक त्रुटि के परिणामस्वरूप होगा, गूंज "नहीं मिली"। @ स्टीफनचेज़लस, क्या मुझे कुछ याद आया?
वाइल्डकार्ड

1
@Wildcard, आप सही कह रहे हैं, मैंने स्पष्ट रूप से अनदेखी की है -q। उस टिप्पणी से समझ में आया होगा [ `grep PATTERN file.txt ` ], लेकिन जैसा कि टिप्पणी में संकेत दिया गया है, [ "`grep -n PATTERN file.txt`" ]बेहतर होगा कि PATTERN केवल खाली लाइनों से मेल खाए। हालांकि यहाँ निश्चित रूप से यह if grep -q PATTERN file.txtआप चाहते हैं।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.