Is it possible to have an awk command within a bash script return values to a bash variable, i.e.,if my awk script does some arithmetic operations, can I store the answers in variables so, they can be accessed in the bash script. If possible, how to distinguish between multiple return variables. Thanks.
No. You can use exit
to return an error code, but in general you can't modify the shell environment from a subprocess.
You can also, of course, print the desired content in awk and put it into variables in bash by using read
:
read a b c <<< $(echo "foo" | awk '{ print $1; print $1; print $1 }')
Now $a
, $b
and $c
are all 'foo'. Note that you have to use the <<<$()
syntax to get read to work. If you use a pipeline of any sort a subprocess is created too and the environment read
creates the variables in is lost when the pipeline is done executing.
source <(awk '{...processing...} END {print "a=" a_val ";b=" b_val ";c=" c_val}')
–
Veracity read -d '' a b c <<< $(echo "foo" | awk '{ print $1; print $1; print $1 }')
to make it work. –
Ingunna coproc
for doing this repetitively by using only 1 fork to awk
–
Gardol var=$(awk '{ print $1}')
This should set var to the output of awk. Then you can use string functions or whatever from there to differentiate within the value or have awk print only the part you want.
result=$(awk 'BEGIN { print "result from awk" }'); echo $result
–
Ingratiating var=$( awk NF=1 )
- that statement is shell safe to be left unquoted, cuz although it looks like a command line assignment for awk,
in the absence of anything else, that statement becomes the main "pattern" –
Deltadeltaic I know this question is old, but there's another way to do this that's worked really well for me, and that's using an unused file descriptor. We all know stdin (&0), stdout (&1), and stderr (&2), but as long as you redirect it (aka: use it), there's no reason you can't use fd3 (&3).
The advantage to this method over other answers is that your awk script can still write to stdout like normal, but you also get the result variables in bash.
In your awk script, at the end, do something like this:
END {
# print the state to fd3
printf "SUM=%s;COUNT=%s\n", tot, cnt | "cat 1>&3"
}
Then, in your bash script, you can do something like this:
awk -f myscript.awk <mydata.txt 3>myresult.sh
source myresult.sh
echo "SUM=${SUM} COUNT=${COUNT}"
To get single string result from awk
in bash
Command substitution
$()
can be used:
result=$(awk 'BEGIN { print "result from awk" }'); echo $result
Equivalent example:
result=$(awk '{print}' <<< "result from awk"); echo $result
my awk script does some arithmetic operations
If you plan to do some arithmetic operations repetitively, you could run awk
(or bc
, but this work with date
, sed
, and near every Un*X filters) in background:
coproc AWK {
exec stdbuf -o0 -i0 awk '{ print sqrt($1), $1^2, 4*atan2($1,1); }'
}
awkPid=$!
ps $awkPid
PID TTY STAT TIME COMMAND
85915 pts/3 S 0:00 awk { print sqrt($1), $1^2, 4*atan2($1,1); }
echo >&${AWK[1]} 25
read -ru ${AWK[0]} line
echo $line
5 625 6.12327
for i in {1..10}; do
echo >&${AWK[1]} $i
read -ru ${AWK[0]} sqr pow ata
printf '%3d %7.3f %4d %8.5f\n' $i $sqr $pow $ata
done
1 1.000 1 3.14159
2 1.414 4 4.42859
3 1.732 9 4.99618
4 2.000 16 5.30327
5 2.236 25 5.49360
6 2.449 36 5.62259
7 2.646 49 5.71560
8 2.828 64 5.78577
9 3.000 81 5.84056
10 3.162 100 5.88451
exec {AWK[0]}<&-
exec {AWK[1]}>&-
[1]+ Done coproc AWK { exec stdbuf -o0 -i0 awk '{ print sqrt($1), $1^2, 4*atan2($1,1); }'; }
ps $awkPid
PID TTY STAT TIME COMMAND
exit
© 2022 - 2024 — McMap. All rights reserved.