正则表达式 / sed - 如何在 72 个字符限制之前匹配一行中的最后一个空格字符



我正在尝试编写一个命令,该命令将通过在任何相关行中的字符 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:]]* 个空格,即零个或多个空格。

最新更新