【问题标题】:Breaking long lines at ~80 characters and prepending characters to each new line以约 80 个字符断开长行并将字符添加到每个新行
【发布时间】:2021-11-19 14:48:53
【问题描述】:

我有几行非常长的文本,基本上我想在 80 个字符标记之前或之上的字边界处硬换行(中断)。但是,我还需要在每个新断行前添加字符,如下所示:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque viverra euismod pulvinar. Fusce quis nibh commodo, commodo massa eu, ultricies nisi. Phasellus ac nulla odio.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque viverra
    \ euismod pulvinar. Fusce quis nibh commodo, commodo massa eu, ultricies
    \ nisi. Phasellus ac nulla odio.

我找到了许多打破长行的方法,但没有一个我能够修改以生成像上面这样的输出,而且我不能在事后简单地附加它,因为这会将行扩展又是 80 个字符。

谁能推荐一个与 Vim 兼容的正则表达式或本机命令来执行上述格式化?使用 sed 或 fmt 或其他外部工具的东西也很受欢迎,但在这种情况下,我可以在 Vim 中使用的东西会更受欢迎。

到目前为止我的发现和尝试:

我确信我缺少一些相当简单的东西,但我坚持如何使用这种条件格式来中断 80 个字符之前的最后一个空格。任何建议将不胜感激。谢谢。

【问题讨论】:

    标签: regex vim line-breaks


    【解决方案1】:

    你需要修改两点:

    • 用零到 80 的量词 \{0,80} 替换恰好 80 的量词(或 \{0,78},因为您似乎希望有 80-2=78 的限制,因为 \t\\ 将是您要插入的两个额外字符)
    • 在末尾添加一个尾随单词边界,\>
    • \t\\ 添加到替换模式以在创建的行中插入TAB 字符和\

    你可以使用

    :%s/.\{0,78}\>/&\r\t\\/g
    

    【讨论】:

    • 谢谢,维克托。这非常接近,但是当我添加生成上述格式所需的其他字符时,我仍然得到超过 80 列的文本: :%s/.\{0,80}\>/&\r\t\\/g
    • @Jared 你的意思是应该从 80 中减去 \t\\(添加两个字符)吗?然后使用 80-添加字符的数量。
    • 是的,没错。带前导“\”的总行长度不应超过 80 个字符。已经开始使用 76 个字符(如您在最新更新中显示的那样)来进行补偿。这过度缩短了第一行,但我认为我可以忍受。
    【解决方案2】:

    冗长的awk 命令也可以很好地完成这项工作:

    awk -v n=76 '
    {
       len = 0
       for (i=1; i<=NF; ++i) {
          len += 1 + length($i)
          printf "%s", $i
          if (len > n && i < NF) {
             printf "%s\t\\ ", ORS
             len = 6
          }
          else
             printf "%s", OFS
        }
        print ""
    }' file
    
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque viverra
        \ euismod pulvinar. Fusce quis nibh commodo, commodo massa eu, ultricies
        \ nisi. Phasellus ac nulla odio.
    

    对于下面提供的第二个示例,我得到以下输出:

    _Array1DToHistogram _ArrayAdd _ArrayBinarySearch _ArrayColDelete _ArrayColInsert
        \ _ArrayCombinations _ArrayConcatenate _ArrayDelete _ArrayDisplay _ArrayExtract
        \ _ArrayFindAll _ArrayInsert _ArrayMax _ArrayMaxIndex _ArrayMin _ArrayMinIndex
        \ _ArrayPermute _ArrayPop _ArrayPush _ArrayReverse _ArraySearch _ArrayShuffle
    

    每行的长度为:

    80
    80
    79
    79
    

    【讨论】:

    • 感谢您的建议!测试一下,我得到了我为 Wiktor 的解决方案描述的相同行为 - 匹配行长时似乎没有考虑前置字符的额外空间,所以这也有一些超过 80 个字符的行。
    • 这似乎不对,因为我重置了len = 6,这是换行后填充字符的长度。可能您可以提供可以重现此问题的示例数据吗?
    • 当然。这是我实际使用的数据的前几行,它们演示了问题:_Array1DToHistogram _ArrayAdd _ArrayBinarySearch _ArrayColDelete _ArrayColInsert _ArrayCombinations _ArrayConcatenate _ArrayDelete _ArrayDisplay _ArrayExtract _ArrayFindAll _ArrayInsert _ArrayMax _ArrayMaxIndex _ArrayMin _ArrayMinIndex _ArrayPermute _ArrayPop _ArrayP
    • 我已经使用您提供的第二个示例运行了这个awk 命令,并且还显示了每行的长​​度。请注意,它永远不会超过80
    • 啊,我明白了。由于制表符扩展,这是文本/字节列和显示列之间的区别。所以是的,将 \t 视为单个字符,它不超过 80,正如您所指出的那样。
    猜你喜欢
    • 2013-11-17
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 2015-01-25
    • 1970-01-01
    相关资源
    最近更新 更多