【问题标题】:sed ignoring triple backtickssed 忽略三个反引号
【发布时间】:2020-09-02 11:48:58
【问题描述】:

我要换

```javascript
something
```

{code}javascript
something
{code}

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

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

它输出我想要的:{code}javascript a23231 {code} 但是,当我使用包含新行的文件运行 sed 时,它无法正确执行。 我试图用 \ 分隔反引号,但它不是我想要的输出。

我做错了什么?

【问题讨论】:

    标签: sed backticks


    【解决方案1】:

    默认情况下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 将整个输入文件转换为单个字符串
    • ```(.*?)``` 将尽可能少地匹配反引号 sn-ps
    • {code}$1\{code} 需要替换,$1 将有捕获组匹配的文本
      • 由于某种原因,{} 导致替换部分出现问题,这就是第二个{ 被转义的原因。我认为它与hash 语法冲突
    • 需要s 标志以允许. 也匹配换行符
    • 如果您需要就地编辑,请使用 -i 选项

    如果-z 选项可用并且三个反引号之间的内容不能有反引号,则使用sed

    $ 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 也可以工作。

    【讨论】:

    • 谢谢您的回答,使用 perl 比让 sed 多行操作更容易吗?
    • perl比较灵活,但sed -z如果满足答案中提到的条件也可以工作
    • @PedroGonzalez 刚刚意识到sed 's/```/{code}/g' ip.txt 也可能对你有用
    猜你喜欢
    • 2018-03-24
    • 2016-06-28
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多