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

Cor*_*ein 14 arrays string bash escaping

我有一个以下格式的字符串:

I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms
Run Code Online (Sandbox Code Playgroud)

我想将它逐行移动到一个字符串数组,以便:

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

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

$ echo "${ARRAY[2]}"
I'm\nDusty\nBottoms
Run Code Online (Sandbox Code Playgroud)

但是,我遇到了字符串本身中"\n"字符的问题.它们在字符串中表示为两个单独的字符,反斜杠和'n',但是当我尝试进行数组拆分时,它们会被解释为换行符.因此,典型的字符串拆分IFS不起作用.

例如:

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

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

$ echo "${ARRAY[1]}"
der
Run Code Online (Sandbox Code Playgroud)

jor*_*anm 28

默认情况下,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"
Run Code Online (Sandbox Code Playgroud)

为了在单行中执行此操作(就像您尝试过的那样read -a),实际上需要mapfile在bash v4或更高版本中:

mapfile -t arr <<< "$string"
Run Code Online (Sandbox Code Playgroud)


che*_*ner 12

mapfile更优雅,但可以在一个(丑陋)行中执行此操作read(如果您使用的是早于4的bash版本,则非常有用):

IFS=$'\n' read -d '' -r -a arr <<< "$string"
Run Code Online (Sandbox Code Playgroud)

  • 当我发布此内容时,我不知道一个警告:退出状态将是非零,因为此处的字符串永远不会像“read -d ''”那样以空字符结尾。 (2认同)