7

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!

  • grep '::= BEGIN' filename &> /dev/null and then check $?. – Nykakin Jun 11 '15 at 10:01
  • 2
    @Nykakin grep has -q option, which does same job as &> /dev/null – Sergiy Kolodyazhnyy Jun 11 '15 at 10:02
  • I have a sed version for you =) – A.B. Jun 11 '15 at 12:29
6

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.

  • The user who downvoted the answer, please leave a comment explaining why you downvoted the answer – Sergiy Kolodyazhnyy Jun 11 '15 at 9:52
  • 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. – SamFlynn Jun 11 '15 at 10:17
  • @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 Jun 11 '15 at 10:20
  • @user2446359 edit is done, please see it – Sergiy Kolodyazhnyy Jun 11 '15 at 10:26
  • Thank you so much Serg! Made my day. I will use the echo $? and store it in a variable. – SamFlynn Jun 11 '15 at 10:51
6

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=$((!$?))
4

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.

3

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
  • 2
    Good job bro ! I like it – Sergiy Kolodyazhnyy Jun 11 '15 at 12:42
  • @terdon corrected – A.B. Jun 11 '15 at 19:22
2

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.