我知道允许SHELL
在命令之前立即进行变量赋值,这样就IFS=":" read a b c d <<< "$here_string"
可以了......
我想知道的是,当使用诸如循环之类的复合语句完成时,这样的赋值是否不起作用?我尝试过类似的操作IFS=":" for i in $PATH; do echo $i; done
,但会导致语法错误。我总是可以做类似的事情oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"
,但我想知道是否有任何方法可以使此类内联赋值适用于for
循环等复合语句?
答案1
for
是一个保留字,因此如下特别规则:
以下字应被视为保留字:
! { } case do done elif else esac fi for if in then 直到 while
仅当没有引用任何字符并且该单词用作以下内容时,才会发生这种识别:
命令的第一个词
除以下保留字外的一个保留字之后的第一个字案件,为了, 或者在
case 命令中的第三个字(仅在在这种情况下有效)
for 命令中的第三个单词(仅在和做在这种情况下有效)
如果你试试
IFS=":" for i in $PATH; do echo $i; done
那么根据上面的规则,这不是循环for
,因为关键字不是命令的第一个单词。但你可以获得所需的输出
tr ':' '\n' <<< "$PATH" #Bash, Ksh, Zsh
printf "%s\n" "$PATH" | tr ':' '\n' #Any standard shell
其中每个都tr
替换:
为换行符。
您可能熟悉这种有效的方法:
while IFS= read -r line; do
while
是命令的第一个字,并且IFS
分配适用于read
,所以一切正常。
答案2
Shell 宏赋值允许在简单命令(例如read
)之前进行,但不允许在复合语句(例如 )之前进行for
。
推荐使用:
OIFS=$IFS
IFS=:
some complex commands
IFS=$OIFS