यदि बैश के साथ फ़ाइल में स्ट्रिंग मौजूद है तो परीक्षण कैसे करें?


337

मेरे पास एक फ़ाइल है जिसमें निर्देशिका नाम हैं:

my_list.txt :

/tmp
/var/tmp

यदि मैं उस नाम को पहले से फ़ाइल में मौजूद है, तो मैं निर्देशिका नाम जोड़ने से पहले बैश में जाँच करना चाहूँगा।


किसी फ़ाइल के अंदर के सभी स्ट्रिंग्स को खोजने के लिए, आप फॉर लूप में grep चला सकते हैं: unix.stackexchange.com/a/462445/43233
Noam Manos

जवाबों:


655
grep -Fxq "$FILENAME" my_list.txt

बाहर निकलने की स्थिति 0 (सत्य) है यदि नाम मिला, 1 (झूठा) यदि नहीं, तो:

if grep -Fxq "$FILENAME" my_list.txt
then
    # code if found
else
    # code if not found
fi

व्याख्या

इसके लिए मैन पेजgrep के संबंधित अनुभाग इस प्रकार हैं :

grep [options] PATTERN [FILE...]

-F, --fixed-strings

        PATTERN को निश्चित स्ट्रिंग्स की एक सूची के रूप में व्याख्या करें, जिसे नई सूचियों द्वारा अलग किया गया है, जिनमें से किसी का मिलान किया जाना है।

-x, --line-regexp

        केवल उन मैचों का चयन करें जो पूरी लाइन से मेल खाते हों।

-q, --quiet,--silent

        चुप; मानक आउटपुट के लिए कुछ भी न लिखें। यदि कोई त्रुटि मिली है, तो भी शून्य स्थिति के साथ तुरंत बाहर निकलें। -sया --no-messagesविकल्प भी देखें ।

गलती संभालना

जैसा कि टिप्पणियों में सही ढंग से कहा गया है, उपरोक्त दृष्टिकोण चुपचाप त्रुटि मामलों का इलाज करता है जैसे कि स्ट्रिंग पाया गया था। यदि आप त्रुटियों को अलग तरीके से संभालना चाहते हैं, तो आपको -qविकल्प को छोड़ना होगा , और बाहर निकलने की स्थिति के आधार पर त्रुटियों का पता लगाना होगा:

आम तौर पर, बाहर निकलने की स्थिति 0 है यदि चयनित लाइनें पाई जाती हैं और 1 अन्यथा। लेकिन बाहर निकलने स्थिति 2 है अगर, कोई त्रुटि हुई है, जब तक -qया --quietया --silentविकल्प प्रयोग किया जाता है और एक चयनित लाइन पाया जाता है। हालांकि, ध्यान दें कि POSIX केवल जनादेश, जैसे कार्यक्रमों के लिए grep, cmpहै, और diff, कि गलती की स्थिति में बाहर निकलने का दर्जा 1 से अधिक होना; इसलिए यह उचित है, पोर्टेबिलिटी के लिए, तर्क का उपयोग करने के लिए जो कि 2 के साथ सख्त समानता के बजाय इस सामान्य स्थिति के लिए परीक्षण करता है।

सामान्य आउटपुट को दबाने के लिए grep, आप इसे रीडायरेक्ट कर सकते हैं /dev/null। ध्यान दें कि मानक त्रुटि अप्रत्यक्ष रूप से बनी हुई है, इसलिए जो भी त्रुटि संदेश grepप्रिंट हो सकते हैं वे कंसोल पर समाप्त हो जाएंगे जैसा कि आप चाहते हैं।

तीन मामलों को संभालने के लिए, हम एक caseबयान का उपयोग कर सकते हैं :

case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in
  0)
    # code if found
    ;;
  1)
    # code if not found
    ;;
  *)
    # code if an error occurred
    ;;
esac

2
अगर मैं bash script से इस कमांड को execute करता हूँ तो 0 या 1 को variable में कैसे पकड़ें?
तोरन

6
@ हाल ही में बाहर निकलने की स्थिति का उपयोग करके पहुँचा जा सकता है $?। आप ifस्टेटमेंट के साथ grep कमांड का उपयोग भी कर सकते हैं (जैसा कि अद्यतन उत्तर में दिखाया गया है)।
शॉन चिन

5
आप उपयोग कर सकते हैं grep -Fqx "$FILENAME"और आपको चर सामग्री में regex वर्णों के बारे में चिंता करने की आवश्यकता नहीं है और आपको उन्हें खोज स्ट्रिंग में उपयोग करने की आवश्यकता नहीं होगी।
अगली सूचना तक रोक दिया गया।

4
इस उत्तर को देखने वाले लोगों के लिए कुछ नोट्स: 1) बैश में, 0 हमेशा सच होता है और कुछ भी हमेशा गलत होता है 2) केवल -x फ्लैग का उपयोग करें यदि आप चाहते हैं कि पूरी लाइन बिल्कुल मेल खाए। यदि आप केवल यह जानना चाहते हैं कि क्या फ़ाइल में आपका तार मौजूद है, तो उसे छोड़ दें। यदि आप यह जानना चाहते हैं कि क्या आपकी स्ट्रिंग ठीक-ठीक मौजूद है, लेकिन आवश्यक रूप से एक पूरी लाइन के मिलान के बिना (यानी, पूरे शब्द के रूप में), -w का उपयोग करें।
श्मिट

1
मैं नहीं मिलता है -q / --silentक्या इसकी जरूरत है? इसके गलत तरीके से "ऑल गुड" को एक त्रुटि होने पर भी कोसने के लिए कहता है। अगर मुझे वह सही ढंग से मिल गया। इस मामले के लिए एक दोषपूर्ण अवधारणा लगता है।
लालनिमलवार

90

निम्नलिखित समाधान के बारे में:

grep -Fxq "$FILENAME" my_list.txt

यदि आप सोच रहे हैं (जैसा मैंने किया) -Fxqसादे अंग्रेजी में क्या मतलब है:

  • F: प्रभावित करता है कि कैसे PATTERN की व्याख्या की जाती है (एक रेगेक्स के बजाय निश्चित स्ट्रिंग)
  • x: पूरी लाइन का मिलान करें
  • q: Shhhhh ... न्यूनतम मुद्रण

मैन फाइल से:

-F, --fixed-strings
    Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of which is to be matched.
    (-F is specified by POSIX.)
-x, --line-regexp
    Select only those matches that exactly match the whole line.  (-x is specified by POSIX.)
-q, --quiet, --silent
    Quiet; do not write anything to standard output.  Exit immediately with zero status  if  any  match  is
          found,  even  if  an error was detected.  Also see the -s or --no-messages option.  (-q is specified by
          POSIX.)

5
-F फ़ाइल प्रसंस्करण को प्रभावित नहीं करता है, यह प्रभावित करता है कि कैसे PATTERN व्याख्या की जाती है। आमतौर पर, PATTERN को एक रेगेक्स के रूप में व्याख्या की जाती है, लेकिन -F के साथ इसे एक निश्चित स्ट्रिंग के रूप में व्याख्या किया जाएगा।
एडम एस

41

मेरे दिमाग में तीन तरीके:

1) एक मार्ग में एक नाम के लिए लघु परीक्षण (मुझे यकीन नहीं है कि यह आपका मामला हो सकता है)

ls -a "path" | grep "name"


2) एक फ़ाइल में एक स्ट्रिंग के लिए लघु परीक्षण

grep -R "string" "filepath"


3) regex का उपयोग कर लंबे बैश स्क्रिप्ट:

#!/bin/bash

declare file="content.txt"
declare regex="\s+string\s+"

declare file_content=$( cat "${file}" )
if [[ " $file_content " =~ $regex ]] # please note the space before and after the file content
    then
        echo "found"
    else
        echo "not found"
fi

exit

यदि आप किसी भी पुटी पर रेगेक्स को बदलते हुए उदाहरण के लिए लूप का उपयोग करते हुए फाइल कंटेंट पर कई स्ट्रिंग का परीक्षण करना है तो यह जल्दी हो जाना चाहिए ।


10
$ File_contenet से पहले और बाद में रिक्त स्थान क्यों आवश्यक हैं?
एमिनेज़आर्टस

तेजी से समाधान के लिए प्लस 1 और एक अधिक सामान्य है
वासादामो

19

सरल तरीका:

if grep "$filename" my_list.txt > /dev/null
then
   ... found
else
   ... not found
fi

युक्ति: /dev/nullयदि आप कमांड के बाहर निकलने की स्थिति चाहते हैं, तो भेजें , लेकिन आउटपुट नहीं।


1
या -qजो उपयोग के रूप में ही है --quiet:)
rogerdpack

-qयहां भी सबसे अच्छे उत्तर पर सहमति दें , और चौथे स्थान पर है। इस दुनिया में कोई न्याय नहीं।
दिसंबर को

14

सबसे सरल और सरल तरीका होगा:

isInFile=$(cat file.txt | grep -c "string")


if [ $isInFile -eq 0 ]; then
   #string not contained in file
else
   #string is in file at least once
fi

grep -c फ़ाइल में स्ट्रिंग कितनी बार होती है, की गिनती लौटाएगा।


5

अगर मैंने आपके सवाल को सही ढंग से समझा, तो आपको वही करना चाहिए जो आपको चाहिए।

  1. आप उस निर्देशिका को निर्दिष्ट कर सकते हैं जिसे आप $ चेक चर के माध्यम से जोड़ना चाहते हैं
  2. यदि निर्देशिका सूची में पहले से ही है, तो आउटपुट "पहले से सूचीबद्ध है"
  3. यदि निर्देशिका अभी तक सूची में नहीं है, तो इसे my_list.txt में जोड़ा जाता है

एक पंक्ति में :check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt


आपको grep के आउटपुट का परीक्षण करने की आवश्यकता नहीं है, आप grep -qसीधे grep का उपयोग और कॉल कर सकते हैं जैसा ifकि थॉमस उसके जवाब में करता है। इसके अलावा, इस सवाल में यह जाँच शामिल नहीं थी कि सूची में जोड़ने से पहले निर्देशिका मौजूद है (यह हटाए गए निर्देशिकाओं की सूची हो सकती है, आखिरकार)।
बोरिपाल

मैंने उदाहरण स्क्रिप्ट को हटा दिया, इसने थॉमस द्वारा दिए गए उत्तर में कुछ भी नहीं जोड़ा।
लेकोडोडाईसेफ

3

यदि आप केवल एक पंक्ति के अस्तित्व की जांच करना चाहते हैं, तो आपको एक फ़ाइल बनाने की आवश्यकता नहीं है। उदाहरण के लिए,

if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ; then
  # code for if it exists
else
  # code for if it does not exist
fi  

3

Fgrep का उपयोग करके मेरा संस्करण

  FOUND=`fgrep -c "FOUND" $VALIDATION_FILE`
  if [ $FOUND -eq 0 ]; then
    echo "Not able to find"
  else
    echo "able to find"     
  fi  

मुझे -cविकल्प नहीं दिखता हैfgrep --help
Nam G VU

3
grep -E "(string)" /path/to/file || echo "no match found"

-ई विकल्प बनाता है grep नियमित अभिव्यक्ति का उपयोग करें


1

@ थॉमस के समाधान ने किसी कारण से मेरे लिए काम नहीं किया, लेकिन मेरे पास विशेष पात्रों और व्हाट्सएप के साथ लंबे समय तक स्ट्रिंग थी, इसलिए मैंने बस इसके लिए मापदंडों को बदल दिया:

if grep -Fxq 'string you want to find' "/path/to/file"; then
    echo "Found"
else
    echo "Not found"
fi

आशा है कि यह किसी की मदद करता है


0

एक grep- कम समाधान, मेरे लिए काम करता है:

MY_LIST=$( cat /path/to/my_list.txt )



if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
  echo "It's there!"
else
echo "its not there"
fi

के आधार पर: https://stackoverflow.com/a/229606/3306354


1
फ़ाइल बड़ी होने की स्थिति में बहुत अधिक मेमोरी का उपयोग करता है। स्वीकृत उत्तरgrep -q में वर्णित सबसे कुशल दृष्टिकोण है।
कोडवर्ड

0
grep -Fxq "String to be found" | ls -a
  • grep आपको कंटेंट चेक करने में मदद करेगा
  • ls सभी फाइलों को सूचीबद्ध करेगा

@ThomWiggers मैंने वही कोशिश की और यह मेरे लिए काम कर गया।
शिनॉय शाज़ी

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