bash:将日志分割成可解析的块

bash:将日志分割成可解析的块

log我有一个包含 svn 历史记录的变量:

$ log=$(svn log -r 9:11)
$ echo "%s\n" "$log"
------------------------------------------------------------------------
r9 | stew | 2021-03-06 20:14:57 +0100 (Sat, 06 Mar 2021) | 1 line

Moving things to trunk
------------------------------------------------------------------------
r10 | stew | 2021-03-06 20:16:27 +0100 (Sat, 06 Mar 2021) | 1 line

Adding script svn2redmine
------------------------------------------------------------------------
r11 | stew | 2021-03-06 20:19:38 +0100 (Sat, 06 Mar 2021) | 2 lines

Moving stuff to a file execute permissions.
This is a multi-line message
------------------------------------------------------------------------

我有一个很好的脚本,可以解析各个提交消息。但现在我这样称呼它:

for rev in {9..11}; do
  parse "$(svn log -r $rev)"
done

这意味着,我发出了很多svn log请求,每个请求都建立了与服务器的另一个连接,因此速度很慢。我宁愿:

log=$(svn log -r 9:11)
for commit in "$log"; do
  parse "$commit"
done

但是我怎样才能分成"$log"单独的提交呢?

答案1

我们需要转换"$log"为包含提交的数组。分割需要基于多字符字符串来完成,因此IFS=在这里没有帮助。

log=$(svn log -r 9:11)

... Something here to split "$log" into an array of commits ...

for commit in "${commits[@]}"; do
  parse "$commit"
done

这种分裂是基于这个答案看起来像这样:

delimiter='------------------------------------------------------------------------'
export -a commits
while [ "$log" != "${log#*$delimiter}" ]; do
   part="${log%%$delimiter*}"
   part="${part##$'\n'}"
   commits+=("${part%%$'\n'}")
   log="${log#*$delimiter}"
done

在哪里:

  • "${log#*$delimiter}"删除第一个分隔符之前(并包括)的所有内容
  • "${log%%$delimiter*}"提取直到(但不包括)下一个分隔符的所有内容
  • "${part##$'\n'}"\n删除分隔符末尾的前导
  • "${part%%$'\n'}"\n删除消息末尾的尾随

相关内容