在 for 循环之前临时更改 IFS

在 for 循环之前临时更改 IFS

我知道允许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

相关内容