在列工具中,`wrapnl` 列属性是如何工作的?
我想用 git log --pretty=format 和 column 的组合来生成一个表格。理想的输出大致像是:
Age Commit Message Author
21 hours ago Update to 3.14.15 Speedy
I made these changes, blah blah blah
1 year, 5 months ago Fix this issue X Speedy
Other info
Link to something
3 years ago Make a really big change to the code Speedy
Cue a long list of things that were changed.
- foo
- bar
- baz
然而,最接近我现在能做到的则是:
Age Commit Message Author
21 hours ago Update to 3.14.15
I made these changes, blah blah blah
Speedy
1 year, 5 months ago Fix this issue X
Other info
Link to something
Speedy
3 years ago Make a really big change to the code
Cue a long list of things that were changed.
- foo
- bar
- baz
Speedy
经过一些变体(因为我已经尝试解决这个问题有一段时间了),我的获取提交的命令是
commits="$(git log --pretty=format:$'%cr\t%s\n%b\t%an')"
而我的表格打印命令是
column -t -s$'\t' -E2 -C'name=Age' -C'name=Commit Message,wrapnl' -C'name=Author,right' <<<"$commits"
我尝试过的一些方法:
- 将
git-log的输出通过管道送入tr '\n' '\r',在column下设置--wrap-separator $'\r' - 所有内容都在一个单元格中,因为每个列表项的换行也被回车符(CR)所替代
- 给
--pretty:format追加 '\x00',将git-log的输出通过管道送入tr '\n' '\r' | sed 's/\x00\r/\n/g',并为column设置--wrap-separator $'\r' - 与前一点的结果相同,可能是因为
tr消除了空字符 - 将前两点的做法结合起来,但把
column下的wrapnl替换为wrap - 与之前相同的结果
- 使用
column的各自独立的--table-*选项 - 与之前相同的结果
写到这里,我想接下来尝试将每条提交的信息单独追加到一个bash数组中,方法是遍历 git log --pretty=format:'%H' 的结果(返回提交哈希值)。这样,我就能更容易地控制每一项的控制字符。
解决方案
正如预期,我通过遍历哈希列表解决了这个问题——这可能并不理想,因为每个哈希都需要重新调用 git。 (编辑:) 对于大型仓库来说会花很长时间——这台笔记本最高时钟频率只有1 GHz,在Arch Linux linux 软件包的日志上大约花了13秒(因此我放弃了这个梦想。不过,若再多加改动,还是有可能实现的)。
# Get list of commit hashes
hashes="$(git log --pretty=tformat:'%H')"
if [ "${#hashes}" -eq 0 ]; then
echo 'ERROR: No commits found' >&2
exit 1
fi
# Get array of commit info
declare -a commits
while read -r hash; do
commits+=("$(git show --no-patch --pretty=format:"$gitformat" "$hash" | tr '\n' '\r' | sed 's/\r/\n\t/g')") # `tr` is needed here because `sed` works line-by-line
done <<<"$hashes"
# Print data
column --table --separator $'\t' --keep-empty-lines -C'name=Age' -C'name=Commit Message,noextreme,wrap' -C'name=Author,right' <(printf '%s\n' "${commits[@]}")
在 git log 步骤中,使用 --pretty=tformat 而非 --pretty:format 十分重要,因为如果没有跟随前者提供的尾随换行符,read 将跳过最后一个条目。
有趣的部分(git show ...)通过把提交信息中的换行符转换成回车符来实现——这并非完全安全,但我觉得出现其中一个这种字符的概率很低——随后使用 sed 把回车符转换成换行符再跟一个制表符。制表符用来把行推到第二列,因此若列数增多,可能需要更多的制表符。之所以要先把换行符改为中间字符,是因为 sed 是按行处理的;否则,我觉得这相当于无操作。
最后,是打印阶段。这里唯一可能让人困惑的部分是 --keep-empty-lines 标志。它的作用是在每条条目之间保留一个空行,便于阅读。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。