
這是輸出:
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'