sed忽略三个backticks



我想更换

```javascript
something
```

带有

{code}javascript
something
{code}

现在,当我在一个带有javascript something(所有内容都在同一行,没有新行(的文件上运行sed时

sed -e 's/```(.*)```/{code}1{code}/' sedfile

它输出我想要的:{code}javascript a23231 {code}但是,当我用一个有新行的文件运行sed时,它做得不好。我试着用\来找出回溯,但它不是我想要的输出。

我做错了什么?

默认情况下,sed一次只操作一行(基于换行符(。有一些方法可以改变这一点,但如果您可以在单行(非贪婪匹配(中进行多个匹配,perl将更适合
$ cat ip.txt
foo ```xyz``` baz ```javascript 123```
```javascript
something
```
$ perl -0777 -pe 's/```(.*?)```/{code}$1{code}/gs' ip.txt
foo {code}xyz{code} baz {code}javascript 123{code}
{code}javascript
something
{code}
  • -0777将整个输入文件作为单个字符串
  • ```(.*?)```将尽可能少地匹配回溯代码段
  • {code}$1{code}需要替换,$1将具有捕获组匹配的文本
    • 由于某种原因,{}导致替换部分出现问题,这就是第二个{被转义的原因。我认为它与hash语法冲突
  • s标志也需要允许.匹配换行符
  • 如果需要就地编辑,请使用-i选项

使用sed,如果-z选项可用,并且三个回溯之间的内容不能有回溯:

$ sed -zE 's/```([^`]+)```/{code}1{code}/g' ip.txt
foo {code}xyz{code} baz {code}javascript 123{code}
{code}javascript
something
{code}

-z选项使sed使用ASCII NUL作为分隔符,而不是换行符。如果输入文件具有NUL字符,则此解决方案将不起作用。

编辑:刚刚意识到,如果输入格式像这里使用的示例一样良好,那么简单的sed 's/```/{code}/g' ip.txt也可以工作。

最新更新