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"
成單獨的送出呢?
我們需要轉換
"$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
消息末尾的尾隨