Use sed command to apply a condition to check if a pattern has been matched

34,700

Solution 1

grep does that job well enough.

$ echo "::=BEGIN" > testfile1.txt

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND

$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND

What the code does is simply running a quiet search within subshell. && , or logical AND operand, checks if the first command succeeded, and if it did, then it runs echo "FOUND" . || checks if that echo has been run, i.e., if we found anything. Second echo runs only if the first command failed.

Here's an awk version:

$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT

$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND

Basic idea here is to set i to NOTFOUND, and if we find the string - change it to FOUNDIT . At the end after the first set of has finished processing file, we will print i, and it will tell us if we found something or not.

Edit: In the comment you mentioned that you want to place the result into a variable. Shell already provides a variable that reports exit status of the previous command, $0. Exit status 0 means success, everything else - fail. For instance,

$ grep "::=BEGIN" -q testfile1.txt  
$ echo $?
0

If you want to use exit status in a variable, you can do it like so : MYVAR=$(echo $?). Remember , $? report exit status of previous command. So you must use this right after the grep command.

If you want to still use my earlier awk and grep one-liners, you can use same trick MYVAR=$() and place whatever command you want between the braces. The output will get assigned to variable MYVAR.

Solution 2

With a GNU sed (as is installed by default on any Ubuntu system):

{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile

Some facts about this answer:

  1. sed Quits input just as soon as the very first match is found anywhere in the file - which means it does not waste any more time continuing to read the infile.

  2. sed returns in its exit code the numeric value 0 or 1 depending on whether it couldn't/could find the addressed regexp.

  3. $i is set to sed's return upon exit.

  4. The { grouping ; } is used to robustly handle any possible redirection error - $i is not set in the case the shell cannot open the file at all, thus avoiding false positives.

This probably shouldn't be preferred to grep -q, though, which can basically also do all of the above (if in reverse), do it POSIXly, and usually faster.

The already given grep -q answer is very good, but, a little terser:

grep -q pattern ./infile; i=$((!$?))

Solution 3

You can use this:

#!/bin/bash
while IFS= read -r line; do
    case "$line" in *::=BEGIN*) i=1 && break;;         
                               *) i=0
    esac
done <file.txt

This will search the file file.txt line by line and if a match of ::=BEGIN found it will set the variable i=1 and exit. If no match is found, the variable will be set as i=0.

Solution 4

My sed version

sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'

to store in a variable i:

i=$(sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}')

Example:

$ echo "::=BEGIN" > foo
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1
$ echo "::=NOT_BEGIN" > foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
0
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1

Explanation:

  • If ::=BEGIN is found, print a 1 and jump to next
  • If ::=BEGIN is not found, print 0

Solution 5

sed (Stream EDitor) is not the right tool for this kind of things: you can simply use a bash if statement to match your input against a regex:

#!/bin/bash

#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
  • input="$(< inputfile)": assigns the content of inputfile to the variable $input
  • [[ "$input" =~ ::=BEGIN ]] && i=1 || i=0: matches the regex ::=BEGIN against the content of the variable $input; if there's a match it assigns 1 to $i, otherwise it assigns 0 to $i
Share:
34,700

Related videos on Youtube

SamFlynn
Author by

SamFlynn

TRON LIVES

Updated on September 18, 2022

Comments

  • SamFlynn
    SamFlynn over 1 year

    I am searching for the string ::=BEGIN and I want to apply a condition to check if the word has been found.

    So, what I mean is something along these lines:

    if (sed command does find a match for "::=BEGIN")
    then i=1 
    else i=0
    

    Also, I want the 1 (for yes found) and 0 (not found) to be put into the variable "i".

    Please help me out. Also provide a explanation to the solution! Thanks!

  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 9 years
    The user who downvoted the answer, please leave a comment explaining why you downvoted the answer
  • SamFlynn
    SamFlynn almost 9 years
    I don't know about the downvote (I don't have the rep points to do anything). I lack much knowledge in GREP and SED(which is my main focus at this point of time). Any Idea on some good resources where i can do SED from? Already looked up Google most of the websites don't explain properly, they just use slashes here and their and stuff gets replaced and exchanged blah blah blah.
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 9 years
    @user2446359 yes, that's sed's syntax, which at times can turn into a gigantic mess. Besides it is a tool for editing stuff, not searching. grep is the right tool for that. In your original question you did not mention putting the result into a variable. Please add that. I'll edit my answer in a second to address this requirement
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 9 years
    @user2446359 edit is done, please see it
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 9 years
    see the comments under my answer
  • SamFlynn
    SamFlynn almost 9 years
    Thank you so much Serg! Made my day. I will use the echo $? and store it in a variable.
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy almost 9 years
    Good job bro ! I like it