我在脚本中使用以下命令来获取合成 wifi 信息:
echo "$(
iw dev wlp1s0 link |
grep '^\s*SSID:\s' |
sed -r 's/^\s*SSID:\s//'
) $(
iw dev wlp1s0 link |
grep '^\s*signal:\s' |
sed -r 's/^\s*signal:\s//'
)"
它有效,输出如下:
MySSID -46 dBm
iw dev wlp1s0 link
然而,当我知道结果将是相同的时,两次进行相同的调用感觉很愚蠢。另外,我想避免将输出存储iw
在临时变量中。
我可以做些什么,也许使用tee
,将输出“复制”到iw
两个作业,然后连接结果?
答案1
使用临时变量并没有什么问题:变量是用来存储要多次使用的数据的。
在这种情况下,您可以将两个 grep/sed 调用合并为对 GNU grep、sed 或 awk 的单个调用。使用 sed 很容易:传递-n
选项以仅输出显式打印的行,并打印进行替换的行。
echo "$(
iw dev wlp1s0 link |
sed -nr -e 's/^\s*SSID:\s//p' -e 's/^\s*signal:\s//'
)"
与原始脚本有一个区别:SSID 和信号值按照它们在 的输出中出现的顺序打印iw
。如果您想独立于该顺序,那么使用 sed 会很麻烦,因此 awk 将是首选工具。通过这种方法,可以很容易地在一行上获得输出。以下脚本打印每个设置的最后一个值(iw
仅输出一个,因此在这种特定情况下它并不重要);更改例如ssid = $0
以ssid = ssid " " $0
打印全部。
iw dev wlp1s0 link | awk '
$1=="SSID:" {sub(/[^:]*:[[:space:]]*/,""); ssid = $0}
$1=="signal:" {sub(/[^:]*:[[:space:]]*/,""); signal = $0}
END {print ssid, signal}
'
一般来说,如果您想将命令的输出发送到两个不同的过滤器,您可以使用tee
并将其传递给流程替代。这是一个 bash 功能(来自 ksh93,也存在于 zsh 中,但不存在于普通 sh 中),它概括了管道。该tee
命令看到一个文件名,该文件名指定连接到指定命令的管道。
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//'
此方法的一个限制是进程替换中的命令在其自己的子 shell 中运行。您无法从中获取变量或控制其输出如何与其他输出散布。
答案2
这是该命令的一行iw
,其输出与您相同。
iw dev wlp1s0 link | grep 'SSID:\|signal' | awk '{printf "%s ", $2$3}'
我的输出:
ZyXEL-AP-2,4GHz -46dBm
答案3
类似的东西?
iw dev wlp1s0 link |
grep -E '^\s*(SSID|signal):\s' |
sed -r 's/^\s*(SSID|signal):\s//' |
awk '{printf $0}'
grep
将接受(SSID|signal):
,因此它将匹配SSID:
和signal:
。
-E
是可选的,但如果您不使用它,请考虑转义特殊含义字符。在这里,将是\(SSID\|signal\):
相同的正则表达式可用于该sed
部分。
最后,使用awk
删除所有尾随换行符(否则,输出将显示为 2 行)。