在换行符上分割字符串并使用 read 将其写入数组

在换行符上分割字符串并使用 read 将其写入数组

给定 string foo,我想将它的每个字段存储\n到 array 的元素中bar。我想使用read命令或与旧版本的 bash 兼容的任何其他命令(但readarray不是)来执行此操作。

我尝试了这个命令:

IFS=$'\n' read -d '' -r -a bar <<< "$foo"

但它只返回错误代码 1。

有什么命令可以用来完成我想要的事情吗?我知道我可以迭代地执行此操作,但显然仅使用一个命令执行此操作是首选。

答案1

read返回 1,因为在字符串中看不到分隔符。但是,该数组已填充:

$ echo "$BASH_VERSION"
3.2.57(1)-release
$ foo=$'one\ntwo\nthree\nfour'

$ IFS=$'\n' read -d '' -r -a bar <<<"$foo"
$ echo $?
1
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three" [3]="four")'

使用非空分隔符会产生非零结果:

$ unset bar
$ IFS=$'\n' read -d "\034" -r -a bar <<<"${foo}\034"
$ echo $?
0
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three" [3]="four")'

八进制 34 是 ASCII“文件分隔符”字符,并且是不太可能出现在您的数据中。

答案2

@glenn jackman 的第一个解决方案的稍微简短的变体:给定

foo=$'one\ntwo\nthree\nfour'

,我们让 Bash 来做全部工作:

set -o noglob         # See special Note, below.
IFS=$'\n' bar=($foo)
set +o noglob         # See special Note, below.

括号告诉 Bash 我们正在初始化一个数组,其元素就是括号内的内容。就这样,完成了。

编辑添加      笔记:*如果输入行可能包含像or 这样的通配元字符?man 7 glob具有完整列表),那么我们必须防止文件名扩展;例如,通过暂时禁用noglob.感谢您抓住这一点,戈登·戴维森!



确认有效:

echo ${#bar[@]}
4

, 和

echo "[0]:'${bar[0]}' ... [3]:'${bar[3]}'"
[0]:'one' ... [3]:'four'


echo "$BASH_VERSION"
4.1.2(2)-release

相关内容