【发布时间】:2014-03-19 21:28:57
【问题描述】:
我正在尝试将子shell 的输出行读入一个数组,但我不愿意设置 IFS,因为它是全局的。我不希望脚本的一部分影响以下部分,因为这是不好的做法,我拒绝这样做。在命令之后恢复 IFS 不是一个选项,因为在编辑脚本后将恢复保持在正确的位置太麻烦了。我如何向 bash 解释我希望每个数组元素包含一整行,而不必设置任何会破坏未来命令的全局变量?
这是一个显示 IFS 不需要的粘性的示例:
lines=($(egrep "^-o" speccmds.cmd))
echo "${#lines[@]} lines without IFS"
IFS=$'\r\n' lines=($(egrep "^-o" speccmds.cmd))
echo "${#lines[@]} lines with IFS"
lines=($(egrep "^-o" speccmds.cmd))
echo "${#lines[@]} lines without IFS?"
输出是:
42 lines without IFS
6 lines with IFS
6 lines without IFS?
【问题讨论】:
-
您可以保存 IFS 的值并在完成“特殊”值后恢复它。这做了很多。
-
即使保存和恢复也比必要的工作要多 - 您可以完全以
read命令本身的本地方式设置 IFS。 -
听起来您正在使用
IFS=$'\n'; array=( $value )来拆分值。这不能正常工作,除非你也set -f。改用 mapfile 或 while 读取循环。 -
确实——
array=( $(command) )是邪恶的。永远不要那样做。 -
@ByronHawkins,不,它不符合您的要求。看看当
$(command)在其输出中包含*时会发生什么情况,该IFS中的字符包围着它。 (...或者不是被IFS的字符包围,如果你启用了shopt -s nullglob;在这种情况下,带有方括号的输出也会充满惊喜)。