How to insert shell variable inside awk command
Solution 1
If you want to /grep/
with your variable, you have 2 choices :
interface=eth0
awk "/$interface/{print}"
or
awk -v interface=eth0 '$0 ~ interface{print}'
See http://www.gnu.org/software/gawk/manual/gawk.html#Using-Shell-Variables
Solution 2
it's like I thought,
awk
substitutes variables properly, but between//
, inside regex ( orawk
regex, depending on someawk
parameter AFAIR),awk
variable cannot be used for substitution
I had no issue grepping with variable inside an awk
program (for simple regexp cases):
sawk1='repo\s+module2'
sawk2='@project2\s+=\s+module2$'
awk "/${sawk1}/,/${sawk2}/"'{print}' aFile
(Here the /xxx/,/yyy/
displays everything between xxx
and yyy
)
(Note the double-quoted "/${sawk1}/,/${sawk2}/"
, followed by the single-quoted '{print}'
)
This works just fine, and comes from "awk: Using Shell Variables in Programs":
A common method is to use shell quoting to substitute the variable’s value into the program inside the script.
For example, consider the following program:
printf "Enter search pattern: "
read pattern
awk "/$pattern/ "'{ nmatches++ }
END { print nmatches, "found" }' /path/to/data
The awk program consists of two pieces of quoted text that are concatenated together to form the program.
- The first part is double-quoted, which allows substitution of the pattern shell variable inside the quotes.
- The second part is single-quoted.
It does add the caveat though:
Variable substitution via quoting works, but can potentially be messy.
It requires a good understanding of the shell’s quoting rules (see Quoting), and it’s often difficult to correctly match up the quotes when reading the program.
Comments
-
Rafael Adel almost 2 years
I'm trying to write a script, In this script i'm passing a shell variable into an awk command, But when i run it nothing happens, i tried to run that line only in the shell, i found that no variable expansion happened like i expected. Here's the code :
1 #!/bin/bash 2 3 # Created By Rafael Adel 4 5 # This script is to start dwm with customizations needed 6 7 8 while true;do 9 datestr=`date +"%r %d/%m/%Y"` 10 batterystr=`acpi | grep -oP "([a-zA-Z]*), ([0-9]*)%"` 11 batterystate=`echo $batterystr | grep -oP "[a-zA-Z]*"` 12 batterypercent=`echo $batterystr | grep -oP "[0-9]*"` 13 14 for nic in `ls /sys/class/net` 15 do 16 if [ -e "/sys/class/net/${nic}/operstate" ] 17 then 18 NicUp=`cat /sys/class/net/${nic}/operstate` 19 if [ "$NicUp" == "up" ] 20 then 21 netstr=`ifstat | awk -v interface=${nic} '$1 ~ /interface/ {printf("D: %2.1fKiB, U: %2.1fKiB",$6/1000, $8/1000)}'` 22 break 23 fi 24 fi 25 done 26 27 28 finalstr="$netstr | $batterystr | $datestr" 29 30 xsetroot -name "$finalstr" 31 sleep 1 32 done & 33 34 xbindkeys -f /etc/xbindkeysrc 35 36 numlockx on 37 38 exec dwm
This line :
netstr=`ifstat | awk -v interface=${nic} '$1 ~ /interface/ {printf("D: %2.1fKiB, U: %2.1fKiB",$6/1000, $8/1000)}'`
Is what causes
netstr
variable not to get assigned at all. That's becauseinterface
is not replaced with${nic}
i guess.So could you tell me what's wrong here? Thanks.