2

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 because interface is not replaced with ${nic} i guess.

So could you tell me what's wrong here? Thanks.

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

6 Comments

Hmm, but what does / / do ?
to be exact, // in awk means to process only lines matching pattern contained between them, like condition, i.e. only lines matching expression are considered as valid to be processed by awk program. Honestly, I can't remember right now if awk variables can be used as pattern ( or how, if so ), and I happen to be too tired to play with it, however you could try $(...) instead of ``, or maybe expression-enclosings trick ( you can use any character instead of // defining start and end of expression,like %..% or any other.Sort of last resort way is using external file with awk program separately.
try using "interface" variable somewhere else in awk program, e.g. within printf(),to make sure if it's really variable substitution, or only use of variable inside // matching (reg)expression.
consider these three simple awk programs: dtpwmbp:~ pwadas$ ls | awk '/^a/ { print $1;}' aa.sh aaa.sh azz.jpg dtpwmbp:~ pwadas$ ls | awk '/^aa/ { print $1;}' aa.sh aaa.sh dtpwmbp:~ pwadas$ ls | awk '/sh$/ { print $1;}' aa.sh aaa.sh dtpwmbp:~ pwadas$
yup, it's like I thought, awk substitutes variables properly, but between //, inside regex ( or awk regex, depending on some awk parameter AFAIR ), awk variable cannot be used for substitution, like with ls | awk -v ptrn=aa '/ptrn/ { print $1 ptrn;}' <= this prints ptrn in print, but doesn't use "aa" inside // expression. Good luck, good night :)
|
2

it's like I thought, awk substitutes variables properly, but between //, inside regex ( or awk regex, depending on some awk 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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.