Bash

bash:將日誌拆分為可解析的塊

  • April 8, 2021

我有一個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"成單獨的送出呢?

我們需要轉換"$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消息末尾的尾隨

引用自:https://unix.stackexchange.com/questions/644091