3

I want to be able to call a shell script contining the following command.

awk -F $'\xE7' '{OFS ="¬"} { $3 = sprintf("%010s". $3) ; print $0 }' > outputfile

But I want to be able to pass a shell script variable into this command which will be used to replace the $3 within the AWK command.

How do I pass a shell script variable into this AWK command?

3 Answers 3

-1

Single quotes inhibit expansion. Switch them up.

awk ... '...'"$foo"'...' ...
5
  • 1
    No! This treats the value of foo, surrounded by double quotes, as a piece of awk script. If $foo contains double quotes or backslashes, all hell may break loose. See Dennis's answer for a solution that works. Oct 27, 2010 at 20:23
  • @Gilles: There is no surrounding by double quotes. The shell removes all external quotes before passing, and since the single quotes are closed before the double quotes are opened and vice versa, they are considered external quotes. Oct 27, 2010 at 20:34
  • Oh, right, I'd misparsed your quotes, and what you wrote is sort-of sensible — the value of foo becomes a fragment of awk script — but then I don't see how it answers the question. @mattm123: I don't understand exactly what you're trying to do, but if you were thinking of using the contents of a shell variable as a string in awk, see Dennis's answer. Oct 27, 2010 at 20:51
  • Gilles is right that if $foo can contain unsanitized values, it may seriously mess up your script.
    – dubiousjim
    Apr 19, 2012 at 10:28
  • ... Consider what happens to awk '$1=='"$foo"'{print $3}' when $foo evaluates to z{next} {print "garbage"} 0. And even in the ordinary case where $foo contains an ordinary string, you'll have to make sure your script places "s around it. Dennis' answer shows the right way to do this.
    – dubiousjim
    Apr 19, 2012 at 10:37
5

The correct way to do this is using AWK's variable passing feature. Also, you probably only need to set OFS once, so you should do it in the BEGIN clause.

awk -F $'\xE7' -v awkvar="$shellvar" 'BEGIN {OFS ="¬"} { $3 = sprintf("%010s". $3) ; print $0, awkvar }' input file > outputfile

You could also use -v to set OFS:

awk -F $'\xE7' -v awkvar="$shellvar" -v OFS ="¬" '{ $3 = sprintf("%010s". $3) ; print $0, awkvar }' input file > outputfile

I just added the variable to the print statement since I didn't know exactly how you wanted to use it.

3
  • @Gilles: Quotes aren't necessary for that type of assignment. Oct 27, 2010 at 23:35
  • Huh? As far as the shell is concerned, awkvar="$shellvar" is the fifth word in the simple command. Without quotes, awkvar=$shellvar would undergo field splitting and pathname expansion as usual. Oct 27, 2010 at 23:42
  • @Gilles: You are right. Sorry, I was thinking about normal shell assignment rules. Oct 27, 2010 at 23:49
2

awk has ENVIRON array for accessing environment:

$ FOO=bar awk 'BEGIN{print ENVIRON["FOO"]}'
bar
1
  • This also works, but the -v technique is the preferred general solution.
    – dubiousjim
    Apr 19, 2012 at 10:39

You must log in to answer this question.

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