首页 > 解决方案 > 如何用 sed 替换部分多行字符串

问题描述

我想用<br/>不在三重反引号语句内的所有地方替换字符串中的换行符(```)

细绳:

This is some requirements just talking about c++ with
`char` types supported by C++:
```
using SecureString = BasicSecureString<char>;
using WSecureString = BasicSecureString<wchar_t>;
using U16SecureString = BasicSecureString<char16_t>;
using U32SecureString = BasicSecureString<char32_t>;
```
And continuing to write
stuff

预期结果:

This is some requirements just talking about c++ with<br/>`char` types supported by C++:<br/>```
using SecureString = BasicSecureString<char>;
using WSecureString = BasicSecureString<wchar_t>;
using U16SecureString = BasicSecureString<char16_t>;
using U32SecureString = BasicSecureString<char32_t>;
```<br/>And continuing to write<br/>stuff

我目前拥有的是这样的:

sed --null-data '/```.*```/!s/\n/<br\/>/g'

但它只适用于不包括反引号的输入。

有人有任何提示吗?

标签: sed

解决方案


perlawk

perl -0777 -pe 's#```.*?```(*SKIP)(*F)|\n#<br/>#sg'

awk '/```/{f=!f} {ORS = f ? RS : "<br/>"} 1'

perl解决方案类似于您尝试使用的sed.

  • -0777将 slurp 整个输入文件,类似于sed -z-z通过使用 ASCII NUL 作为行分隔符来工作
  • ```.*?```(*SKIP)(*F)以防止此匹配部分被更改
  • |\n指定应该匹配的内容
  • <br/>替换字符串
  • s允许.匹配换行符的标志

使用时,输出记录分隔符会根据输入具有三个反引号时awk更改的值进行更改。f这种方法的优点是不必对整个输入进行啜饮。


如果您不想更改文件中的最后一个换行符,请使用

perl -0777 -pe 's#```.*?```(*SKIP)(*F)|\n(?!\z)#<br/>#sg'

推荐阅读