使用 sed/awk/grep 格式化 git 日志输出

xco*_*rat 4 regex git bash awk sed

摘要/“要点”版本,

如果我有一组带有主题[SUB]和正文的消息,如下所示,仅当主题存在时[BODY],如何在主题后添加换行符(并将占位符替换为)[BODY]*

[SUB] some subject. [BODY] some body lines 
with newline chars and !@@# bunch of other *#@ chars
 without [(BODY)] or [(SUB)]... and more stuff
[SUB] Another subject. with no body [BODY] 
[SUB] another [BODY] some body.
Run Code Online (Sandbox Code Playgroud)

我希望其格式如下

* some subject.

some body lines 
with newline chars and !@@# bunch of other *#@ chars
 without [(BODY)] or [(SUB)]... and more stuff
* Another subject. with no body 
* another 

some body.
Run Code Online (Sandbox Code Playgroud)

我真正想做的事

所以我尝试从git log输出自动生成 CHANGELOG.md 文件。问题是,仅当提交消息的正文非空时,我才需要放置换行符。

当前的代码如下所示(分为两行)

git log v0.1.0..v0.1.2 --no-merges --pretty=format:'* %s -- %cn | \
[%h](http://github.com/../../commit/%H) %n%b' | grep -v Minor | grep . >> CHANGELOG.md
Run Code Online (Sandbox Code Playgroud)

和样本输出,

* Added run information display (0.1.2) -- ... | [f9b1f6c](http://github.com/../../commit/...) 
+ Added runs page to show a list of all the runs and run inforation, include sorting and global filtering.
+ Updated run information display panel on the run-info page
+ Changed the links and their names around.

* Update README.md -- abc | [2a90998](http://github.com/../../commit/...) 

* Update README.md -- xt | [00369bd](http://github.com/../../commit/...) 
Run Code Online (Sandbox Code Playgroud)

您在这里看到,以 开头的行*是提交,以 开头的行+只是第一次提交的正文的一部分。现在,它会%n在所有正文部分前面添加一个(换行符),无论它是否为空。我只想在它非空时添加它(甚至可能在删除空格之后)

我将如何实现这一目标?我对sed和 的了解awk几乎不存在,尝试学习并没有多大帮助。

(我可以确保正文中的所有代码都缩进,因此不会将提交列表与正文中的列表混淆)


我的答案

我确信 jthills 的答案是正确的(甚至可能是更好的方法),但是当我想弄清楚他的意思时,我想到了这一点。希望它对我自己或将来的某人有帮助,

我正在粘贴我使用的完整 shell 脚本,

mv CHANGELOG.md CHANGELOG.md.temp
printf '### Version '$1' \n\n' > CHANGELOG.md
git log $2..$1 --no-merges --pretty=format:'[SUB]%s -- %cn | \
    [%h](http://github.com/<user>/<gitrepo>/commit/%H) [BODY]%b' | grep -v Minor | \
    sed '{:q;N;s/\s*\[BODY\][\n\s]*\[SUB\]/\n\[SUB\]/;b q}' | \
    sed 's/\[SUB\]/* /g' | 
    sed 's/\[BODY\]/\n\n/'>> CHANGELOG.md
cat CHANGELOG.md.temp >> CHANGELOG.md
rm CHANGELOG.md.temp
Run Code Online (Sandbox Code Playgroud)

我基本上使用临时文件将新的提交日志添加到 CHANGELOG.md 中。请随意建议这 3 个sed命令的较短版本

jth*_*ill 5

在输出中标记您的语法git log。这将正确处理插入换行符,其余的你知道:

git log --pretty=tformat:'%s%xFF%x01%b%xFF%x02' \
| sed '1h;1!H;$!d;g              # buffer it all (see comments for details)
       s/\xFF\x01\xff\x02//g     # strip null bodies
       s/\xFF\x01/\n/g           # insert extra newline before the rest
       s/\xFF.//g                # cleanup
'
Run Code Online (Sandbox Code Playgroud)

编辑:引用/转义错别字)