Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass shell parameters to awk does not work

Tags:

bash

awk

Why does this work

for myfile in `find . -name "R*VER" -mtime +1`
do
   SHELLVAR=`grep ^err $myfile || echo "No error"`
   ECHO $SHELLVAR
done

and outputs

No error
err ->BIST Login Fail 3922 err 
No error
err ->IR Remote Key 1 3310 err 

But this does not

for myfile in `find . -name "R*VER" -mtime +1`
do
   SHELLVAR=`grep ^err $myfile || echo "No error"`
   awk -v awkvar=${SHELLVAR} '{print awkvar}'
done

and outputs

awk: cmd. line:1: fatal: cannot open file `{print awkvar}' for reading (No such file or directory)

What am I missing?

like image 574
Chris Avatar asked Dec 07 '22 21:12

Chris


1 Answers

Does $SHELLVAR contain a space? If so, your awk script is getting misparsed, and the {print awkvar} is being assumed to be a file name and not the actual AWK program.

You also have a problem where both your for loop and the awk program are both slurping STDIN. In fact, your for loop would only be executed once since the AWK will read in all the STDIN until it finishes. In the end, you'll get the same line over and over, and then your program will stop running as the awk awaits for more STDIN.

I think you want to do something like this...

find . -name "R*VER" -mtime +1 | while read myfile
do
    echo "$SHELLVAR" | awk '{print $0}'
done

This way, your echo command feeds into your awk which will prevent awk from reading from the find statement.

As an aside, you're better off doing this:

find . -name "R*VER" -mtime +1 | while read myfile
do
   ...
done

Rather than this:

for myfile in `find . -name "R*VER" -mtime +1`
do
   ...
done

This is for several reasons:

  1. The command line buffer could overflow, and you'll lose file names, but you'll never see an error.

  2. The find command in the second example must first complete before the for loop can start to execute. In the first example, the find feeds into the while loop.


ADDENDUM

Now that I saw just-my-correct-opinion's answer, I realize what you've really done wrong: You forgot the file name in the awk command:

find . -name "R*VER" -mtime +1 | while read myfile
do
   SHELLVAR=`grep ^err $myfile || echo "No error"`
   awk -v awkvar=${SHELLVAR} '{print awkvar}' $myfile
done

Now, the question is what exactly are you doing with the awk. You're not printing anything except the value of $SHELVAR for each and every line in the file. That's probably not what you want to do. In fact, why not simply do this:

find . -name "R*VER" -mtime +1 | while read myfile
do
   SHELLVAR=$(grep -q "^err" $myfile")
   if [ "x$SHELLVAR" != "x" ]
   then
      echo "$SHELLVAR"
   fi
done

That way, you print out $SHELLVAR, but only if $SHELLVAR is empty.

Or, you can use awk to print out only those lines that match your regex:

find . -name "R*VER" -mtime +1 | while read myfile
do
   awk '/^err/ {print $0}' $myfile
done
like image 67
David W. Avatar answered Jan 05 '23 12:01

David W.