【问题标题】:How to split a multi-line string containing the characters "\n" into an array of strings in bash? [duplicate]如何将包含字符“\ n”的多行字符串拆分为bash中的字符串数组? [复制]
【发布时间】:2012-07-29 13:42:50
【问题描述】:

我有一个 string 格式如下:

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 对上述代码的可怕格式吗?
  • “可怕的格式”是由于撇号被解释为单引号(它希望是平衡的)。使用“块引用”标签而不是“代码”标签。

标签: arrays string bash escaping


【解决方案1】:

默认情况下,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"

【讨论】:

  • 是的,对于 mapfile oneliner :)
【解决方案2】:

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

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

【讨论】:

  • 确实,-d 选项似乎对使其正常工作至关重要
  • 我在发布此内容时不知道的一个警告:退出状态将非零,因为此处的字符串永远不会以 read -d '' 所期望的空字符结尾。
猜你喜欢
  • 2021-04-05
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
相关资源
最近更新 更多