Using egrep to output expressions which are not found

Hi,

Im using the below command to search a file for multiple expressions if the 4th expression doesnt exist the command simply lists what it can find and ignores what it cant. Is there any way to get the command to output an error or a message if it cant find the 4th expression to a file?

Any help will be much appreciated :slight_smile:

egrep -is 'Schema Area|stock|route_drop|test123' /apps/Main_structure.txt 1>/apps/grep_error.txt
SunOS sants 5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-V490

You can use an egrep -v on a pipe to remove lines that match and an egrep to save lines that match.

Here is an approach using nawk

nawk ' BEGIN {
                IGNORECASE=1;
        } /Schema Area/||/stock/||/route_drop/||/test123/ {
                if($0~/test123/)
                        c++;
                print;
        } END {
                if(c==0) 
                        print "Error: 4th expression not found!";
}' /apps/Main_structure.txt

You can also use sed, where you can act on lines that have a pattern '/pattern/{...}' or not '/pattern/!{...}' or test one inside the other.

if grep -q "Schema Area" file &&
   grep -q stock         file &&
   grep -q route_drop    file && 
   grep -q test123       file
then   
  echo correct
else
  echo incorrect
fi

What does the input file look like?

You can do this in one pass in awk, setting flags for each pattern, discarding input and testing the flags at eof.

sorry I dont have the use of nawk or grep with the -q switch

egrep -v wouldn't get what Im looking for as it wouldnt highlight any errors

sorry I only have limited knowledge of awk and sed so Im not sure how I would use them in this case

What I am looking for is by using grep or egrep or any other command to search though a file for expression1|expression2|expression3 etc... and if it can't find one of the expressions output an error along the lines of "can't find expression1". If it does find the expression in the file then do nothing and output nothing.

Thankyou for all your help so far people :slight_smile:

---------- Post updated at 04:05 AM ---------- Previous update was at 04:01 AM ----------

the input file looks like this and carries on:

 Area Name: Schema Area
Size: 77823936, Records/Block: 64, Area Number: 6
Area Name: stock
Size: 1024192, Records/Block: 64, Area Number: 100
Area Name: route_drop
Size: 4096768, Records/Block: 256, Area Number: 101

You probably do have grep -q somewhere on your system, on Solaris use /usr/xpg4/bin/grep
Otherwise you could use:

if grep "Schema Area" >/dev/null file &&
   grep stock         >/dev/null file &&
   grep route_drop    >/dev/null file && 
   grep test123       >/dev/null file
then   
  echo correct
else
  echo incorrect
fi

or

if { grep "Schema Area" file &&
     grep stock         file &&
     grep route_drop    file &&
     grep test123       file
   } > /dev/null
then
  echo correct
else
  echo incorrect
fi
1 Like

fantastic thank you Scrutinizer that option works perfectly :slight_smile:

not sure why it wont let me use the grep -q option youve posted I get this when I try

grep: illegal option -- q
Usage: grep -hblcnsviw pattern file
/usr/xpg4/bin/grep

does exist though

Good, yes, then you could use /usr/xpg4/bin/grep -q instead of grep -q . That standard grep on Solaris is only present for legacy reasons..

1 Like

That works now too :slight_smile: both produce the same results so is one prefered to the other or doesnt it matter?

It's up to you :slight_smile:

awk '/^size/ && ! NF==6 { print "Something missing" } filename

---------- Post updated at 05:01 PM ---------- Previous update was at 04:56 PM ----------

please ignor my previous post.

 awk '$1 ~ /^Size/ && NF != 7 { print "Something missing"}' filename

Things like -q are command specific, but if you want a silent test, just run the command into a variable:

cmd_oput=$( some_command args ... 2>&1 )

---------- Post updated at 10:51 AM ---------- Previous update was at 10:38 AM ----------

You can do file evaluation in one pass in shell, too, using file globbing metachar:

ct1=0 ct2=0 ct3=0 ct4=0
 
while read l
 do
  case "$l" in
   (*"Schema Area"*)
    (( ct1++ ))
    ;;
   esac
  case "$l" in
   (*stock*) 
    (( ct2++ ))
    ;;
   esac
  case "$l" in
   (*route_drop*) 
    (( ct3++ ))
    ;;
   esac
  case "$l" in
   (*test123*) 
    (( ct4++ ))
    ;;
   esac
 done < in_file
# process counts $ct1-4 to determine response

This one will output the missing pattern

$ echo 'Schema Area|stock|route_drop|test123' | tr '|' '\n' > tmp; grep -Eiof tmp file | grep -v -f- tmp; rm tmp
test123

And, this is DGPickett's proposal, slightly simplified:

while read l
  do case "$l" in
        (*"Schema Area"*)       (( ct1++ ));;
        (*stock*)               (( ct2++ ));;
        (*route_drop*)          (( ct3++ ));;
        (*test123*)             (( ct4++ ));;
     esac
  done < file   

Just remember that if a line has pattern 1, you will miss all other patterns on that line.

Oh ... yes, you are right. In bash, appending a & the ;; making it read ;;& would help. This may not be available in other shells.