我正在尝试编写一个命令,该命令将通过在任何相关行中的字符 72 之后插入换行符来格式化 git 提交消息的文本文件,但不在单词中间。如果字符 72 位于单词中间,则应在字符 72 之前的行中最后一个空格插入换行符。以下:
sed -e "s/.{72}/&n/g" < msg.md
无论单词边界如何,都将在位置 72 处进行插入,但我想不出如何让它正确考虑这些边界。
它可以通过更复杂的 bash/python 脚本或每行完成的东西来完成,但我很好奇它是否可以完全在正则表达式/sed 中完成。
sed 'y/ /³/
s/.*/
&³/
:space
s/(.*n)([^³]{0,72})³/12 /
t space
s/(.*) ([^³]*³)/1
2/
t space
s/.(.*)./1/
' YourFile
- posix 版本如此
--posix
在 GNU sed 上 - 假设里面没有
³
,如果有:使用另一个分隔符或先翻译它,然后在最后返回 - 递归传递每个部分,直到不再有"maximmu,但少于 72 个字符的单词后跟一个空格"
解释:
- 通过用非空格字符替换每个空格来准备递归修改的字符串(此处
³
)+ 添加起始新行和尾随³
- 选择任何标题,后跟一个新行(所以通常是最后一个新行,sed 占据最大的可用部分),后跟最大字符(直到 72
³
),后跟一个³
,并替换为相同的字符,除了最后³
个空格字符(实际上,我使用 2 组,但 1 个就足够了, 它保留在早期测试中) - 如果有替换项,请重试新的事件(以便它达到"最终"空间之前的可用最大值),如果没有继续
- 取一个标头(从完整字符串 [不是当前子字符串] 开头的所有字符)后跟一个空格(因此在当前字符串状态下最后一个可用),后跟一组非
³
和一个³
并将其替换为第一组,空格替换为新行,而不是第二组 - 如果有替换项,请重试整个循环
- 删除开头添加的额外部分(第一个字符[换行],最后一个字符)
对每行执行相同的操作,逐行执行 sed
您可以使用:
sed 's/.{72}[^[:blank:]]*[[:blank:]]*/&n/g' msg.md
[^[:blank:]]*
将匹配 72 个字符后的 0 个或多个非空格,后跟 [[:blank:]]*
个空格,即零个或多个空格。