【问题标题】:Why does my string not split nicely into an array?为什么我的字符串不能很好地分割成一个数组?
【发布时间】:2014-06-30 19:24:03
【问题描述】:

我有那个 bash 脚本,它将把 git show 的输出读入一个数组。

首先,我使用以下语句创建一个字符串:

git show --quiet --date=rfc --pretty=format:"%s|%b|%an, %ae|%H|%cd" HEAD

这给了我想要的模式:

SUBJECT|BODY|AUTHOR_NAME, AUTHOR_EMAIL|COMMIT_HASH|COMMIT_DATE

我可以确认生成的字符串在意想不到的地方包含| 字符。

接下来,我想将字符串拆分为 Split string into an array in Bash 中假设的字段:

  IFS='|' read -ra FIELDS <<< "$(git show --quiet --date=rfc --pretty=format:"%s|%b|%an, %ae|%H|%cd" $i)"

当我现在查看FIELDS 时,只有前两个元素被填充,而其他元素是空的:

echo ${FIELDS[0]} # prints SUBJECT
echo ${FIELDS[1]} # prints BODY
echo ${FIELDS[2]} # prints nothing
echo ${FIELDS[3]} # prints nothing
echo ${FIELDS[4]} # prints nothing

我做错了什么?为什么最后三个数组元素是空的?

【问题讨论】:

  • 你能显示命令的输出吗?就我而言,BODY 条目为空,但多行正文排在最后。
  • @choroba:见下面 l0b0 的答案。问题是git show 用换行符终止了正文,这会破坏数组的创建。

标签: arrays string git bash ifs


【解决方案1】:

正如@l0b0 所指出的,问题是由git show 的输出中的换行符引起的,就在“BODY”之后——read 命令读取了一行,因此它停在那里。您可以使用read -d '' 将其行分隔符从换行符更改为...,从而使其读取整个内容:

IFS='|' read -d '' -ra FIELDS <<< "$(git show --quiet --date=rfc --pretty=format:"%s|%b|%an, %ae|%H|%cd" $i)"

这会将${FIELDS[0]} 设置为“SUBJECT”,将${FIELDS[1]} 设置为“BODY\n”,将${FIELDS[2]} 设置为“AUTHOR_NAME, AUTHOR_EMAIL”等。然而,一个复杂的问题是它还会处理语法换行符在作为最后一个字段的一部分的输出末尾,即${FIELDS[4]} 将设置为“COMMIT_DATE\n”。

【讨论】:

  • 请记住,read -d '' 总是以状态 1 退出,因为从技术上讲,它会在找到行分隔符之前用完输入。
【解决方案2】:

您给出的git show 命令将输出拆分为多行(至少在版本 1.8.3.1 中),即使传递给另一个命令也是如此:

$ git show --quiet --date=rfc --pretty=format:"%s|%b|%an, %ae|%H|%cd" HEAD
SUBJECT|BODY
|AUTHOR_NAME, AUTHOR_EMAIL|COMMIT_HASH|COMMIT_DATE

要解决此问题,您可以在reading 之前将输出通过管道传输到tr -d '\n'

【讨论】:

  • 是的。可以确认此行为。
  • 使用tr 不适合我,因为我想在BODY 中保留换行符。相反,我将在第二次git show 调用中获取正文并手动将其附加到数组中。谢谢!
  • 您也可以使用read -d '' ... 让它一次性读取整个字符串(而不仅仅是第一行)。
  • @GordonDavisson:继续,让您的评论成为答案。虽然 l0b0 的答案指出了错误行为的原因,但您的评论是我的答案。
猜你喜欢
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 2023-01-05
  • 2011-09-13
  • 2021-02-26
相关资源
最近更新 更多