LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   interpret bash positional parameter within awk regex string (https://www.linuxquestions.org/questions/programming-9/interpret-bash-positional-parameter-within-awk-regex-string-4175625259/)

vincix 03-09-2018 08:43 AM

interpret bash positional parameter within awk regex string
 
I've got the following line:
Code:

ip address show | awk -F "[ /]*" '/inet.*eth0/ { print $3 }'
I'm trying to replace 'eth0' with the first bash positional parameter, i.e. $1. I know this can be a little bit tricky in awk, in that you need to declare the variable beforehand with -v. The problem in this case is that the positional parameter would be part of a regex, like this: /inet.*$1/ Of course, I couldn't simply write $1 as such because it seems something different for awk. And if I did arg=$1 then awk -v some_var=$arg, it wouldn't work, "some_var" would be interpreted literally within the regex

Any ideas?

BW-userx 03-09-2018 09:36 AM

the 'replace' part of what you're saying is confusing, but the code says find and print.


You're trying to get the ip for your eth0, I got wlan0 not eth0, so this still applies to the same just change the what you're looking for with a little help from grep ( wlan0 to eth0 ).

  1. ip address show : shows all information
  2. grep 'pattern' : gets you to the specific area where you want to be within all of the information shown.
  3. awk : gets the specific information you want


Code:

$ ip address show | grep wlan0 | awk 'FNR == 2 {print $2}'
1xx.xx.xx.1xx/24

FNR is which line (down) , print $x is which column of that line. In case you or others reading this didn't know.

vincix 03-09-2018 09:57 AM

I don't understand what is confusing exactly about replacing 'eth0' with whatever first positional parameter you're going to call the bash script with. Maybe that was confusing, the fact that I didn't mention that it's supposed to be part of a small bash script, so that I can run it simply like this: "bash_script eth0" - that would show me the ip of 'eth0'.

Your solution does the same thing the line I've written already does. Moreover, I'm using one tool (awk), instead of grep + awk, even if the awk syntax becomes somewhat more complicated. So the point is to use bash positional parameters. That's what I'm looking for.

BW-userx 03-09-2018 10:13 AM

Quote:

Originally Posted by vincix (Post 5829042)
I don't understand what is confusing exactly about replacing 'eth0' with whatever first positional parameter you're going to call the bash script with. Maybe that was confusing, the fact that I didn't mention that it's supposed to be part of a small bash script, so that I can run it simply like this: "bash_script eth0" - that would show me the ip of 'eth0'.

Your solution does the same thing the line I've written already does. Moreover, I'm using one tool (awk), instead of grep + awk, even if the awk syntax becomes somewhat more complicated. So the point is to use bash positional parameters. That's what I'm looking for.

ok, let me try this. You're writing a bash script that takes in values, seeings how it is a script it does not have to be a one liner using only awk. SO if you're taking in that what are you looking for off the command line then using that for awk to use to find what it is you're wanting to print out.

Code:

./scriptName wlan0
changes wlan0 to eth0 no matter what you type in on the frist postion.

Code:

whatIwant=$1
whatIamUsing=eth0

awk -v var="$whatIwant" ....
or
awk -v var="$whatIamUsing" ...

puts first positional parameter into another variable name then use that name to do your dirty work.


see what this does for you
Code:

#!/bin/bash
ip address show | awk -v doop="$1"  '$0~doop{print $2}'

You might have to play with it, so don't be shy.

giving this more thought:
"I'm trying to replace 'eth0' with the first bash positional parameter,"

I am wanting to use the first positional parameter in a bash script instead of hard coding the 'eth0' into my awk to find the device and print out the IP attached to it by piping in the output from the 'ip address show' command into awk.


if that is what you are trying to do.
Code:

$ ./positionalparameter wlan0
wlan0:
134.44.34.321/26


keefaz 03-09-2018 12:02 PM

You could select device in ip show command

Code:

d=eth0
ip a show dev $d | awk -F "[ /]*" '/inet/{print $3}'


scasey 03-09-2018 12:54 PM

Quote:

Originally Posted by vincix (Post 5829026)
I'm trying to replace 'eth0' with the first bash positional parameter, i.e. $1.
...
Any ideas?

As has been said...or at least hinted at, why? Don't hard code anything, just use the variable populated with $1.
You might want to add something like:
Code:

if [[ ! $1 ]]
  then
        echo "usage is namofscript <nic>"
        exit
fi

to your script to remind users that a parameter is required.

rknichols 03-09-2018 01:51 PM

Quote:

Originally Posted by vincix (Post 5829026)
I've got the following line:
Code:

ip address show | awk -F "[ /]*" '/inet.*eth0/ { print $3 }'
I'm trying to replace 'eth0' with the first bash positional parameter, i.e. $1.

Just beak up the quoted string such that "$1" is outside it so that the shell can do the substitution.
Code:

ip address show | awk -F "[ /]*" '/inet.*'$1'/ { print $3 }'
At first glance, it looks as though $1 is enclosed in single quotes. It is not. There is a closing quote, then $1 (unquoted), then an opening quote. When that whole string gets passed to awk it will have $1 replaced by the first positional parameter. As others have pointed out, you should probably ensure that said parameter is non-null in the script.

MadeInGermany 03-09-2018 07:30 PM

While the smart solution is in post#5,
here is how you can handle it with an awk variable
Code:

ip address show | awk -v iface="$1" -F "[ /]*" '$0~("inet.*" iface) { print $3 }'
Code:

ip address show | awk -v iface="$1" -F "[ /]*" 'BEGIN {srch=("inet.*" iface) } $0~srch { print $3 }'
The ~ operator makes the string an RE.

grail 03-09-2018 07:50 PM

Not sure if anyone has tested any of these solutions, but on my machine they just return ALL ip's on the inet lines, ie not just whatever everyone thinks $1 is set to,
which by the way I would think is nothing (which also agrees with my findings)

The pipe is not a bash script nor does it create output for one.

@OP - Exactly what would $1 be in your mind as the output from your command (assuming it did work that way)?

rknichols 03-09-2018 08:22 PM

Quote:

Originally Posted by grail (Post 5829205)
Not sure if anyone has tested any of these solutions, but on my machine they just return ALL ip's on the inet lines, ie not just whatever everyone thinks $1 is set to,
which by the way I would think is nothing (which also agrees with my findings)

The pipe is not a bash script nor does it create output for one.

You might want to reread:
Quote:

Originally Posted by vincix (Post 5829042)
Maybe that was confusing, the fact that I didn't mention that it's supposed to be part of a small bash script, so that I can run it simply like this: "bash_script eth0" - that would show me the ip of 'eth0'.


BW-userx 03-09-2018 08:39 PM

Quote:

Originally Posted by rknichols (Post 5829213)
You might want to reread:

this part is the imporant part.
Quote:

Originally Posted by vincix
So the point is to use bash positional parameters.

everything else is just using the bash positional parameters.
$1
Code:

#!/bin/bash

#ip address show | awk -v doop="$1"  '$0~doop{print $2}'

#ip address show | awk -F "[ /]*" '/inet.*'$1'/ { print $3 }'

ip address show | awk -v iface="$1" -F "[ /]*" 'BEGIN {srch=("inet.*" iface) } $0~srch { print $3 }'


grail 03-09-2018 09:00 PM

Quote:

Originally Posted by rknichols (Post 5829213)
You might want to reread:

My bad :(

In that case I would do:
Code:

ip a s "$1" | awk '/inet/{print gensub(/\/.*/,"",1,$2)}'

BW-userx 03-09-2018 09:42 PM

Quote:

Originally Posted by grail (Post 5829221)
My bad :(

In that case I would do:
Code:

ip a s "$1" | awk '/inet/{print gensub(/\/.*/,"",1,$2)}'


it might work with eth0?
Code:

$ ./positionalparameter wlan0
1XX.3X1.X2.322
fe80::224:d7ff:fecf:9ea4

its using these two to get the output.
Code:

inet
inet6


grail 03-09-2018 10:47 PM

Quote:

Originally Posted by BW-userx (Post 5829226)
it might work with eth0?
Code:

$ ./positionalparameter wlan0
1XX.3X1.X2.322
fe80::224:d7ff:fecf:9ea4

its using these two to get the output.
Code:

inet
inet6


And op made no mention of not wanting ipv6 addresses ... or did I miss that too :(
If that is a requirement, simply put a space after the 't'

BW-userx 03-09-2018 11:03 PM

Quote:

Originally Posted by grail (Post 5829234)
And op made no mention of not wanting ipv6 addresses ... or did I miss that too :(
If that is a requirement, simply put a space after the 't'

I think OP step out for a coffee and has not returned, yet.


All times are GMT -5. The time now is 11:06 PM.