sed 忽略三重反引号

sed ignoring triple backticks

我要更换

```javascript
something
```

{code}javascript
something
{code}

现在,当我 运行 使用 javascript something 对文件进行 sed 时(所有内容都在同一行中,没有新行)

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

它输出我想要的:{code}javascript a23231 {code} 但是当我 运行 sed 一个包含新行的文件时,它没有正确执行。 我尝试用 \ 来分隔反引号,但它不是我想要的输出。

我做错了什么?

默认情况下sed一次只操作一行(基于换行符)。有多种方法可以改变它,但是如果您可以在一行中进行多个匹配(non-greedy 匹配)

perl 会更适合
$ cat ip.txt
foo ```xyz``` baz ```javascript 123```

```javascript
something
```

$ perl -0777 -pe 's/```(.*?)```/{code}\{code}/gs' ip.txt
foo {code}xyz{code} baz {code}javascript 123{code}

{code}javascript
something
{code}
  • -0777 将整个输入文件作为单个字符串处理
  • ```(.*?)``` 将尽可能少地匹配反引号片段
  • {code}\{code} 所需的替换,</code> 将具有捕获组匹配的文本 <ul> <li>出于某种原因,<code>{} 导致替换部分出现问题,这就是第二个 { 被转义的原因。我认为这会导致与 hash 语法
  • 的冲突
需要
  • s 标志以允许 . 也匹配换行符
  • 如果需要 in-place 编辑,请使用 -i 选项

  • With sed if -z 选项可用且三重反引号之间的内容不能有反引号:

    $ sed -zE 's/```([^`]+)```/{code}{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 也可能有效。