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



Question:

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!


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

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


Solution:5

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

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »