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

时间:2013-12-19 17:48:35

标签: regex git bash sed awk

摘要/'版本要点,

如果我有一组包含主题[SUB]和正文[BODY]的邮件,如下所示,如果只有[BODY]存在,如何在主题之后添加换行符(并用[{1}})

替换占位符
*

我想将其格式化为

[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.

我真正想做的事,

所以我试图从* 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. 输出中自动生成我的CHANGELOG.md文件。问题是,只有在提交消息的主体非空时才需要添加换行符。

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

git log

和示例输出,

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

你在这里看到,以* 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/...) 开头的行是提交,而从*开始的行只是第一次提交的正文的一部分。现在它在所有正文部分前面添加+(换行符),无论它是否为空。如果它非空(我甚至可能在删除空格后)

,我想添加它

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

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


我的回答

我确定jthills的回答是正确的(甚至可能是更好的方式),但是当我想弄清楚他的意思时,我想到了这个。希望它能帮助我自己或未来的某个人,

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

awk

我基本上是使用临时文件将新提交日志添加到CHANGELOG.md。请随时为此3 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 命令建议更短的版本

3 个答案:

答案 0 :(得分:3)

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
'

编辑:引用/转义拼写错误)

答案 1 :(得分:1)

对于您问题中的第一个文件,您可以尝试以下操作:

awk -f r.awk input.txt 

其中input.txt是输入文件,r.awk是:

{
    line=line $0 ORS
}

END {
    while (getSub()) {
        getBody()
        print "* " subj
        if (body) {
            print ""
            print body
        }
    }
}

function getBody(ind) {
    ind=index(line,"[SUB]")
    if (ind) {
        body=substr(line,1,ind-1)
        line=substr(line,ind)
    }
    else
        body=line
    sub(/^[[:space:]]*/,"",body)
    sub(/[[:space:]]*$/,"",body)
}

function getSub(ind,ind2) {
    ind=index(line,"[SUB]")
    if (ind) {
        ind=ind+5
        ind2=index(line,"[BODY]")
        subj=substr(line, ind, ind2-ind)
        line=substr(line,ind2+6)
        return 1
    }
    else
        return 0
}

给出输出:

*  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.

答案 2 :(得分:1)

我用这种方式比预期的更长时间摔跤,只是试图通过git消息的一些调整来获取git日志输出来格式化/提取我们的JIRA消息。 这是我的解决方案:

logsheet = "!f() { git log --format='%h ^ %<(80,trunc)%s ^ A:%<(20,trunc)%an ^ D:%ad ' --no-merges --date=short $1 | sed -e 's/\\([A-Z]*-[0-9]*\\)/\\1 ^/'; }; f"

逃脱,shell函数用!都需要因为我有一个arg和一个管道。 : - )