0

I need that awk would return exit code 1 if:

  • no input from grep to awk was provided
  • second field is empty or does not exist

It is working when grep finds "SOME_PHRASE", but if this phrase does not exit, return code ($?) is 0.

grep -m1 -i '^SOME_PHRASE' test.txt | awk '{ if (length($val)==0 || $val=="" || length($2)==0) exit 1; else print $2; }'

example of test.txt

Test1 1234  
Phrase 214324

Expected output:

$ echo $?  
1
5
  • You are right, I can do it only with awk. For example I tried awk '/SOME_PHRASE/ {if (val=="" || $2=="") exit 1; else print $2;}' test.txt, but still does not work
    – Rokas.ma
    Mar 1, 2017 at 13:32
  • add sample input and expected output for various cases...
    – Sundeep
    Mar 1, 2017 at 13:55
  • There seems to be some issue with the if condition. I tried "grep -m1 -i '^SOME_PHRASE' test.txt | awk '{ if (0) exit 1; else exit 5 }'" and this is returning 5.. I tried $ cat test.txt test.txt SOME_PHRASE SOME_PHRASEerewte awk '/SOME_PHRASE/ {if (val=="" || $2=="") exit 1; else print $2;}' test.txt and it is returning 1 .echo $? 1. May be val is getting populated from somewhere. Mar 1, 2017 at 13:57
  • Added example of input and expected output
    – Rokas.ma
    Mar 1, 2017 at 14:15
  • The examples could be made a lot clearer. I couldn't tell what you were trying to do at all until I read your self-answer.
    – Wildcard
    Mar 2, 2017 at 5:30

5 Answers 5

2

You can indeed combine awk and grep:

awk 'BEGIN{rv=1}                      # Default return value is 1
     tolower($0) ~ /^some_phrase/{    # Case insensitive search 
         if($2 != ""){                # If $2 is not empty,
            print $2                  # print the value,
            rv=0                      # and set the return value
         } 
         exit                         # one match, do not process any more line 
     } 
     END{exit rv}
' test.txt
1

I managed to achieve what I wanted.

grep -m1 -i 'SOME_PHRASE' test.txt | awk 'END { if (NR==0 || $2=="")  exit 1; else print $2;}'
1

More straight forward:

$ awk 'toupper($1) ~ /^SOME_PHRASE/ { if ($2) { print $2; exit 0 } else { exit 1 } } END { exit 1 }' test.txt

The first field is changed to uppercase and compared against the uppercase pattern. If matching, and if there exist a second field, that field will be printed and the script exits with a zero exit status, otherwise (no second field) it will exit with an exit status of 1. If the pattern never matches, the script will exit with an exit status of 1 once it reaches the end of input.

1
  • 1
    Saved me the trouble of writing it. :) That's exactly what I was thinking when I finally understood the question.
    – Wildcard
    Mar 2, 2017 at 5:30
1

Aside from the fact that awk is perfectly capable of doing what grep does here, you could also explicitly check for empty input in awk and then return a one. Here an END block checks the number of lines (records) processed:

$ echo foo | grep bar | awk 'END {if (NR == 0) exit  }' ; echo "exit value $?"
exit value 1

Or, use the shell to get the return code of the failing process in the pipeline, even if it's not the last one. I don't think the standard shell can do that, but e.g. in Bash, set -o pipefail:

$ set -o pipefail 
$ echo foo | grep bar | awk '{exit 0}' ; echo "exit value $?"
exit value 1

(Bash also has PIPESTATUS if you want to look at the return values from all the processes in the pipeline.)

0

You should consider moving everything inside one roof/tool to make it simple:

grep -qE '^SOME_PHRASE.*[^[:space:]]' yourfile

perl -0777ne 'exit !/^SOME_PHRASE.*?\S/m' yourfile

sed -ne '/^SOME_PHRASE.*[^[:space:]]/q;$q1' yourfile

Output

For the data shown, immediately after running either of the above commands, we run:

echo "$?"
1

Brief

Perl slurps the whole of yourfile and looks for the keyword at the beginning of a line, which is enabled for multiline strings using //m modifier. The ! is there to account for the fact that SUCCESS in Perl & Unix worlds is complementary.

Sed is operated in don't print unless asked for mode -n and assuming GNU sed which has the q command that includes the exit status as well.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .