简体   繁体   中英

Passing Bash argument into Bash Variable encapsulating AWK Command

I need to be able to run the script and pass in arguments (day and month) like

$root# ./myscript -v 31 12

but I can't seem to find any appropriate way to pass a command line argument into the awk command within the bash variable X without the script choking. I've tried double quotes to allow variable interpolation, escaping the other dollar signs with backslashes as outlined elsewhere on Stack Overflow, but to no avail.

#!/bin/bash
X=$(./some_script | awk -v VARIABLE="$1" '$1 == "VARIABLE" | awk '{print $1,$2,$3}')
Y=$(./other_script | awk -v VARIABLE="$2" '$1 == "VARIABLE" | awk '{print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

This is choking the script and returning an error

awk: syntax error near line 1 
awk: bailing out near line 1

SOLVED Seems that the standard Solaris 'AWK' won't accept the -v flag, and that specific error telegraphed it somewhat. Switched it with nawk and it runs fine as detailed below. @David_W goes into some detail regarding nawk/awk parameter passing. Many thanks to @Ed_Morton for spotting the error and @anubhava and @hek2mgl for the Proof-of-concepts.

#!/bin/bash
echo
X=$(./some_script | nawk -v VARIABLE="$1" '$1 == "VARIABLE" {print $1,$2,$3}')
X=$(./other_script | nawk -v VARIABLE="$1" '$1 == "VARIABLE" {print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

There are two ways of passing environment variables into awk depending upon the version of awk :

Newer versions of awk (sometimes called nawk on Solaris systems):

$ awk -v var1="$var1" -v var2="$var2" prog.awk

Older versions of awk make you set the variables on the end:

$ awk prog.awk var1="$var1" var2="$var2"

I'm not 100% sure if that last one is exactly the way it's done. I haven't used the older version of awk in over 20 years. Even Solaris allows you to use the newer version of awk by either calling nawk instead, or by using the one in /usr/xpg4/bin (which I recommend to put in your $PATH before /bin and /usr/bin . This way, shell scripts from other operating systems like Mac OS X and Linux are more likely to work in a compatible way.)

From the Solaris XPG4 (Section 5) manpage:

If the behavior required by POSIX.2, POSIX.2a, XPG4, SUS, or SUSv2 conflicts with historical Solaris utility behavior, the original Solaris version of the utility is unchanged; a new version that is standard-conforming has been provided in /usr/xpg4/bin . For applications wishing to take advantage of POSIX.2, POSIX.2a, XPG4, SUS, or SUSv2 features, the PATH ( sh or ksh ) or path ( csh ) environment variables should be set with /usr/xpg4/bin preceding any other directories in which utilities specified by those specifications are found, such as /bin , /usr/bin , /usr/ucb , and /usr/ccs/bin .

You can use awk -v name=val to pass an argument to awk from shell:

Try this:

#!/bin/bash
X=$(./some_script | awk -v val="HARDCODED" '$1 == val {print $1,$2,$3}')
Y=$(./some_other_script | awk -v val="HARDCODED" '$1 == val {print $1,$2,$3}')
echo '-------------RESULTS--------------'
echo
paste <(echo "$X") <(echo "$Y")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM