Linux
為什麼 bash read 不會刪除多餘的尾隨 IFS 字元
這個命令:
read -d 'z' a < <(printf 'a\n\n\n'); printf "$a"
輸出:
a
bash
read
刪除了預期的多餘尾隨換行符。並通過更改
IFS
為空字元:
IFS= read -d 'z' a < <(printf 'a\n\n\n'); printf "$a"
它輸出:
a (blank line) (blank line)
read
不再刪除多餘的尾隨換行符,因為IFS
不再包含換行符…但現在如果我們做同樣的事情,但用
m
換行符代替:IFS=m read -d 'z' a < <(printf 'ammm'); printf "$a"
有人會認為輸出是:
a
但實際輸出是:
ammm
即現在
read
不會刪除多餘的尾隨IFS
字元(在本例中為m
字元)。為什麼?
欄位拆分特別忽略了前導和尾隨 IFS 空格。來自GNU Bash 手冊,3.5.7 Word Splitting:
如果
IFS
未設置,或者它的值恰好<space><tab><newline>
是預設值,則忽略前面擴展結果的開頭和結尾處的 、 和 序列,並且任何不在開頭或結尾的字元序列都<space>
用於<tab>
分隔單詞。如果具有非預設值,則在單詞的開頭和結尾處忽略空格字元、和的序列,只要空格字元在 IFS 的值中(一個 IFS 空格字元)。<newline>``IFS``IFS``space``tab``newline
禮貌不會擴展到非空白字元。您可以使用其他欄位拆分實例進行檢查:
bash-5.0$ printf "|%s|\n" $(printf '\n\na\nb\n\n') |a| |b| bash-5.0$ IFS=' '; printf "|%s|\n" $(printf ' a b ') |a| |b| bash-5.0$ IFS=z; printf "|%s|\n" $(printf 'zzazbzz') || || |a| |b| ||