Issue
I didn't find similar solution, apart from parsing multiple arguments which is a whole script by it self.
I need to get handle # from nftables for the script, and having problems because it is not always located on the same position. With Iptables it was line number which was always listed on the first field so was very easy to capture insert position.
when I do:
nft -n -a list chain inet fw4 forward
output would be something like this:
table inet fw4 {
chain forward { # handle 2
type filter hook forward priority 0; policy drop;
ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 accept # handle 223
ct state 0x2,0x4 accept comment "!fw4: Allow forwarded established and related flows" # handle 179
iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic" # handle 180
iifname "eth0.2" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic" # handle 181
jump handle_reject # handle 182
}
}
I need to capture "handle #", which in this case is 223 without any spaces before or after normally I would do:
InsNo=$(nft -n -a list chain inet fw4 forward|grep -m 1 "192.168.0.0"|awk '{print $10}')
which works only when fixed number of fields are present. I tried also
InsNo=$(nft -n -a list chain inet fw4 forward|grep -m 1 "192.168.0.0"|awk -F'handle ' '{print $2}')
which works if no more arguments are present after handle number. But I'd like to know if there is any more reliable method, in getting this number, also without spaces before or after.
Solution
awk
solutions are your easiest option here (and what you asked about), but a potentially "safer" version can be written with sed
by matching both handle
and the consecutive numbers. Just an additional option because... why not.
nft -n -a list chain inet fw4 forward |
sed -En '/192\.168\.0\.0/s/.*# +handle +([0-9]+).*/\1/p'
Final solution was "only first match" and ended up like this:
nft -n -a list chain inet fw4 forward |
sed -En '/192\.168\.0\.0/{s/.*# +handle +([0-9]+).*/\1/p; q}
The ()
parathesis is a capture group, recovered by \1
later on, i.e. returning the match within. [0-9]
matches any digit and the following +
matches "one or more" of that = any number of consecutive digit(s). Th p
prints line to stdout. It's needed as we suppress all lines otherwise with the -n flag. To only print one match, simply encapsulate the substitute in {}
curly brackets and add q
for quit.
Answered By - Kaffe Myers Answer Checked By - Robin (WPSolving Admin)