这是输出:
sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null
亚什·沙阿 核心片段 CoreFragment_5G 核心片段 德联 亚什·沙阿 康法斯特 Appbirds_技术 共生 20096641 CoreFragment_5G 琥珀_AP1 红翼实验室_5G
虽然在脚本中编写的相同内容的工作方式并不相同。
这是我使用上面命令的一个片段。
for ssid_name in $(sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null)
do
echo "$ssid_name"
done
我得到这样的输出:
亚什 沙阿 核心片段 CoreFragment_5G 核心片段 亚什 沙阿 红翼 实验室 康法斯特 Appbirds_技术 共生 CoreFragment_5G 红翼 LABS_5G
笔记:当输出中有空格时,将作为新行。
我正在使用 Ubuntu 18.04。
答案1
首先请注意,它不是一命令的行为不同。在您的代码片段中,标准输出是由两个完全不同的命令编写的。
您的第一个打印sed
的输出,而在第二个打印中:
- 的输出
sed
被替换(通过命令替换$(...)
)in
; - 结果字符串被扩展为元素列表;
- 每个项目依次分配给
ssid_name
并由 打印echo
。
第 2 点的扩展是根据内部字段分隔符 ( ) 的值进行的IFS
,默认为<space><tab><newline>
。因此,你的解决方案之所以有效,是因为它只允许for
在换行符上分割替换的字符串。
作为您答案的旁白,请注意,它$'\n'
不可移植 - 即使$'string'
许多 shell 都支持该语法 ( )。
不过,您可以使用这样的分配:
IFS='
'
处理输入行的另一种构造是在循环read
中使用while
:
sudo iwlist scan 2>/dev/null | grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null |
while IFS= read -r i; do
printf '%s\n' "$i"
done
在这里,sed
的输出的每一行也根据 的值进行分割IFS
- 在本例中设置为空字符串,以防止任何单词分割的影响 - 但行将保持由read
分隔IFS
。
答案2
最好使用while
循环read
而不是for
循环。
sudo iwlist scan 2>/dev/null |grep ESSID | sed 's/.*ESSID:"\(.*\)".*/\1/' 2>/dev/null | while IFS= read -r ssid_name
do
echo $ssid_name
done
答案3
通过在 for 循环之前在代码中添加以下行,在我的情况下可以正常工作。
IFS=$'\n'