1

I am trying to check if a certain file has two strings. My test file is:
This is line1. This is line2.

In real-time scenario for my application the strings line1 and line2 can be on the same or different lines or have one or more occurrences. The objective is to find if these string exist in the file.

Now, if I run the following command I expect OK to be printed but it doesn't.
cat test_file.sh | awk '$0 ~ /line1/ && /line2/ {print "OK"};'

Can someone please tell what is it that I need to change here.

6
  • you're checking whether both patterns are on the same line. Commented Feb 9, 2016 at 20:34
  • Are they always on consecutive lines or could there be other lines in between? Does the order they appear in matter? Commented Feb 9, 2016 at 21:07
  • @Ed Morton no the order doesn't matter. There can be multiple lines in between. Commented Feb 9, 2016 at 21:08
  • 2
    Then edit your question to say that and show a more interesting/representative/potentially problematic example than 2 consecutive lines. Can the 2 strings be on the same line? State your requirements for that too. Commented Feb 9, 2016 at 21:17
  • 1
    Do we have an OK when the first line is a line with both line1 and line2 and the second line a line with only line2? Commented Feb 9, 2016 at 21:37

4 Answers 4

1

Your awk command is trying to find line1 and line2 on same line. Correct way to search 2 strings on different lines is:

sed '/^[[:blank:]]*$/d' |
awk -v RS= '/line1[^\n]*\n.*line2/ || /line2[^\n]*\n.*line1/{print "Ok"}'
  • sed will remove all blank lines from input
  • -v RS= will set input record separator as NULL thus ignoring new line as record separator.
  • /line1[^\n]*\n.*line2/ || /line2[^\n]*\n.*line1/ will search 2 keywords on 2 different lines irrespective of their order
Sign up to request clarification or add additional context in comments.

4 Comments

awk '/102/{p=1} p && /103/ {print "OK"}' <<< "102103" gives OK, and they are not on different lines.
printf "%s\n%s\n" "line2" "line1" | awk '/line1/{p=NR} p && NR>p && /line2/ {print "OK"}' should give OK.
Yep, but you want it to work too when line2 comes first.
OK, all explicit requirements are met.
1

You can also accomplish this using grep and wc. For example:

cat ./file | grep "line1\|line2" | wc -l

would return the number of lines these two strings ("line1" and "line2") are on. If it returned 1, they are on the same line. If it returned 2, they are on separate lines.

2 Comments

And will also return line1 when line2 is not in the file.
After edit: A file with the substring line1 on 2 different lines will be found twice (sort -u won't help). You should do 2 greps and verify that both have at least one hit.
0

Here we store the line number in which the patterns occur and decide in the end if the input is ok or not.

BEGIN {p1=0; p2=0;}

/This is line1./ { p1 = FNR}
/This is line2./ { p2 = FNR}

END { if( p1== p2 ) {
    print "not ok";
  }
  else {
    print "ok";
  }
}

1 Comment

Also check that both p1 and p2 are > 0. And how about 3 lines, the first only with line1, the second only with line2 and the third with both?
0

awk to the rescue!

awk '/pattern1/{s=1} /pattern2/{t=1} s&&t{print "OK"; exit}' file

checks two patterns regardless of the order.

If you want them to be strictly on different lines

awk '/pattern1/{s=1;next}
     /pattern2/{t=1;next}
           s&&t{print "OK"; exit}
            END{if(s&&t) print "OK"}' file

2 Comments

echo "pattern1pattern2" | awk '/pattern1/{s=1} /pattern2/{t=1} s&&t{print "OK"; exit}' gives OK with both patterns on the same line.
yes would work regardless same line or different, updated code with different lines only.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.