0

in a unix shell script I have

filename=myfile
LOG=/dir/log*
j=`awk '/AAAA/ && /BBB/ && /${filename}/ && /CCC/' ${LOG}`

but when the script runs, with set -x I see:

awk /AAA/ && /BBB/ && /${filename}/ && /CCC/ /dir/log1 /dir/log2

How can I escape the ${filename} variable within the awk argument so that it resolves correctly ?

To illustrate what I am trying to do

I have a file called /tmp/S20150814.001 which contains

This line contains AAAA and BBB and CCC and bcd_input_13082015_0800.txt

In my script, if I use

MYLOG=/tmp/S20150814.001
j=`awk '/AAAA/ && /BBB/ && /bcd_input_13082015_0800.txt/ && /CCC/' ${MYLOG}`
if [[ ${#j} -gt 0 ]]
then

and run the script I see

+ + awk /AAAA/ && /BBB/ && /bcd_input_13082015_0800.txt/ && /CCC/      /tmp/S20150814.001
j=This line contains AAAA and BBB and CCC and bcd_input_13082015_0800.txt
+ [[ 71 -gt 0 ]]

but if I change the script to

MYLOG=/tmp/S20150814.001
filename=bcd_input_13082015_0800.txt
j=$(awk -v filename="$filename" '/AAAA/ && /BBB/ && $0==filename && /CCC/' ${MYLOG})
if [[ ${#j} -gt 0 ]]
then

and run it, I get

+ + awk -v filename=bcd_input_13082015_0800.txt /AAAA/ && /BBB/  &&  $0==filename && /CCC/ /tmp/S20150814.001
j=
+ [[ 0 -gt 0 ]]
  • 1
    Note that "escape" actually means the exact opposite of this. Your problem is that the `$` is *currently* escaped (because it's inside single-quotes), whereas you want the value of `${filename}` to be substituted. (But ghoti's approach is a better one, anyway.) – ruakh Aug 13 '15 at 17:12

2 Answers2

5

You shouldn't put filenames inside the code of your awk script like that. If you need to pass in a variable, awk has an option for that.

j=$(awk -v filename="$filename" '/AAAA/ && /BBB/ && $0~filename && /CCC/' ${LOG})

Or, since your filename might contain characters interpreted as part of a regular expression, perhaps you really want:

j=$(awk -v filename="$filename" '/AAAA/ && /BBB/ && $0==filename && /CCC/' ${LOG})

See also: https://stackoverflow.com/a/9712555/1072112 for some help on how various types of quotes work.

Community
  • 1
  • 1
ghoti
  • 45,319
  • 8
  • 65
  • 104
  • Thank you for the answer, but it did not seem to work. The awk command appeared as + + awk -v filename=myfile /AAAA/ && /BBB/ && $0==currentfile && /CCC/ /log/dir1 and the variable j was null – user3478415 Aug 13 '15 at 19:49
  • You are setting a variable named `filename` and testing a variable named `currentfile`. Awk is not magic... :-). – Ed Morton Aug 13 '15 at 19:58
  • sorry I should have written + + awk -v filename=myfile /AAAA/ && /BBB/ && $0==filename && /CCC/ /log/dir1 – user3478415 Aug 13 '15 at 20:01
  • 1
    You should be copy/pasting output, not writing it. If that command is producing no output it means that your input file has no line that matches that condition. Edit your question to show sample input and expected output if you'd like more help. It is very possible we are misinterpreting what it is you wanted your non-functioning script to actually do. – Ed Morton Aug 13 '15 at 20:03
0

I got this to work by

j=$(awk -v filename="$filename" '/AAAA/ && /BBB/ && $0 ~ filename && /CCC/' ${MYLOG})

ie a space was needed before and after the "~"