如何在bash中将包含字符"\n"的多行字符串拆分为字符串数组?

24

我有一个字符串,格式如下:

I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms

我想将这个逐行移动到一个字符串数组中,使其如下:

$ echo "${ARRAY[0]}"
I'm\nNed\nNederlander

$ echo "${ARRAY[1]}"
I'm\nLucky\nDay

$ echo "${ARRAY[2]}"
I'm\nDusty\nBottoms

然而,我在字符串本身中遇到了"\n"字符的问题。它们在字符串中表示为两个不同的字符,反斜杠和 'n',但当我尝试使用数组拆分时,它们被解释为换行符。因此,使用 IFS 进行典型的字符串拆分将无法正常工作。

例如:

$ read -a ARRAY <<< "$STRING"
$ echo "${#ARRAY[@]}"   # print number of elements
2

$ echo "${ARRAY[0]}"
I'mnNednNederla

$ echo "${ARRAY[1]}"
der

顺便问一下,有人知道如何修复SE对上面代码的可怕格式吗? - Cory Klein
“可怕的格式”是由于撇号被解释为单引号(它期望平衡)所致。请使用“块引用”标记而不是“代码”标记。 - twalberg
2个回答

39

默认情况下,read内置命令允许使用\来转义字符。如果要关闭此行为,请使用-r选项。通常情况下,您不会遇到不想使用-r的情况。

string="I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms"

arr=()
while read -r line; do
   arr+=("$line")
done <<< "$string"

为了实现一行代码(就像您尝试使用read -a一样),实际上需要在bash v4或更高版本中使用mapfile
mapfile -t arr <<< "$string"

地图文件一行代码太棒了 :) - electronix384128

17

mapfile 更加优雅,但是如果你使用的是早于 4 版本的 Bash,则可以在一行(丑陋的)代码中使用 read 来实现:

IFS=$'\n' read -d '' -r -a arr <<< "$string"

确实,使用-d选项似乎是使其正常工作的关键。 - Vic Seedoubleyew
2
我在发布这篇文章时不知道的一个警告是:退出状态将是非零的,因为类似于“read -d''”期望以空字符结尾的字符串将永远不会以空字符结束。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接