There's nothing wrong with using a temporary variable: variables are made to store data to be used several times.
In this case, you can combine the two grep/sed calls into a single call to GNU grep, sed or awk. It's easy with sed: pass the -n
option to output only explicitly printed lines, and print the lines on which a substitution is made.
echo "$( iw dev wlp1s0 link | sed -nr -e 's/^\s*SSID:\s//p' -e 's/^\s*signal:\s//' )"
There is one difference from your original script: the SSID and signal values are printed in the order they appear in the output of iw
. If you wanted to be independent of that order, it would be cumbersome with sed, so awk would be the tool of choice. With this approach, it's just as easy to get the output on a single line. The following script prints the last value for each setting (iw
only outputs one, so in this specific case it doesn't matter); change e.g. ssid = $0
to ssid = ssid " " $0
to print them all.
iw dev wlp1s0 link | awk ' $1=="SSID:" {sub(/[^:]*:[[:space:]]*/,""); ssid = $0} $1=="signal:" {sub(/[^:]*:[[:space:]]*/,""); signal = $0} END {print ssid, signal} '
In general, if you want to send the output of a command to two different filters, you can use tee
and pass it a process substitution. This is a bash feature (from ksh93, also present in zsh, but not in plain sh) that generalizes pipes. The tee
command sees a file name that designates a pipe which is connected to the specified command.
iw dev wlp1s0 link | tee >( grep '^\s*SSID:\s' | sed -r 's/^\s*SSID:\s//' ) | grep '^\s*signal:\s' | sed -r 's/^\s*signal:\s//'
A limitation of this approach is that the command in the process substitution runs in its own subshell. You can't get variables back from it or control how its output is interspersed with others.