bash: 로그를 구문 분석 가능한 덩어리로 분할

bash: 로그를 구문 분석 가능한 덩어리로 분할

logsvn 기록을 포함하는 변수가 있습니다.

$ 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메시지 끝에서 후행 제거

관련 정보