【问题标题】:Replace matching START END lines替换匹配的 START END 行
【发布时间】:2020-04-16 00:48:22
【问题描述】:

我正在尝试替换多行上的两个匹配模式,仅替换匹配的 startend 行,并将行保留在 startend 之间。

我尝试使用 sed、awk、Python、Perl 结合此处的一些答案,但没有运气。

这就是我所拥有的:

other text

```term
command1
```

other text

```term
command1
command2
```

other text

```js
code
```

替换后的文本应如下所示:

other text

{{< terminal >}}
command1
{{< /terminal >}}

other text

{{< terminal >}}
command1
command2
{{< /terminal >}}

other text

```js
code
```

基本上,我想用{{&lt; /terminal &gt;}} 替换每个匹配的包含term with `{{&lt; terminal &gt;}}` and 的行。

我无法进行简单的搜索并替换包含startend 模式的行,因为end 可以匹配我想要保留的其他start 行。

【问题讨论】:

  • 抱歉,不清楚,能否请您在问题中发布更清晰的示例示例,然后让我们知道?
  • 基本上我想用 {{&lt; terminal &gt;}} 和 ``` 用 {{}} 替换包含 ``` 术语的每个匹配行。

标签: regex shell perl awk sed


【解决方案1】:

请您尝试关注一下。

awk -v start="{{< terminal >}}" -v end="{{< /terminal >}}" '
/```/ && found==""{
  if(rest_of_values){
    print rest_of_values
    rest_of_values=""
  }
  found=1
  val1=$0
  next
}
/```/ && found==1{
  print start ORS rest_of_values ORS end
  rest_of_values=found=""
  next
}
{
  rest_of_values=(rest_of_values?rest_of_values ORS:"")$0
}
END{
  if(rest_of_values){
    print val1 ORS rest_of_values
  }
}
'  Input_file

代码负责什么:

  • 它会查找成对的 ``` 字符串,如果找到了一对,那么只有它会更改其值。
  • 如果一对没有完成,那么它也会打印这些行的值(基本上没有更改的行)。

说明:在此添加对上述代码的详细说明。

awk -v start="{{< terminal >}}" -v end="{{< /terminal >}}" '      ##Starting awk program from here with variable values start and end here.
/```/ && found==""{                                               ##Checking condition if ``` is found in a line and variable found is NULL then do following.
  if(rest_of_values){                                             ##Checking condition if variable rest_of_values is NOT NULL then do following.
    print rest_of_values                                          ##Print variable rest_of_values here.
    rest_of_values=""                                             ##Nullifying variable rest_of_values here.
  }                                                               ##Closing BLOCK for above if condition here.
  found=1                                                         ##Setting variable found variable value as 1 here.
  val1=$0                                                         ##Setting variable val1 value as current line value here.
  next                                                            ##next will skip all further statements from here.
}                                                                 ##Closing BLOCK for /```/ && found==""{ condition here.
/```/ && found==1{                                                ##Checking condition if ``` is found and variable found is NOT NULL then do following.
  print start ORS rest_of_values ORS end                          ##Printing value of variable start,ORS,rest_of_values,ORS and end variable here.
  rest_of_values=found=""                                         ##Nullifying variables rest_of_values and found here.
  next                                                            ##next will skip all further statements frmo here.
}                                                                 ##Closing BLOCK for condition /```/ && found==1{ here.
{
  rest_of_values=(rest_of_values?rest_of_values ORS:"")$0         ##If above both conditions are NOT matching then creating a variable rest_of_values, keep concatenating its own value each time it comes here.
}
END{                                                              ##Starting END BLOCK for this awk program here.
  if(rest_of_values){                                             ##Checking condition if variable rest_of_values is NOT NULL then do following.
    print val1 ORS rest_of_values                                 ##Printing values val1 ORS rest_of_values here.
  }
}                                                                 ##Closing BLOCK for END BLOCK of this awk code here.
'  Input_file                                                     ##Mentioning Input_file name here.

【讨论】:

  • 谢谢!我只需要将第一个匹配的 ``` 更改为 ``` 术语并删除“val1 ORS”部分。
【解决方案2】:

perl 版本:

while (<>){
    if  (/```term/ ... /```/){
        if  (/```term/){
            print "{{< terminal >}}\n";
            next;
        } elsif (/```/) {
            print "{{< /terminal >}}\n";
            next;
        }
    }
    print;
}

运行命令:

perl test.pl input-file

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed):

    sed -i '/^```term/{s//{{< terminal >}}/;:a;n;/^```/!ba;s//{{< \/terminal >}}/}' file
    

    搜索以```term 开头的行,将其替换为{{&lt; terminal &gt;}} 继续获取和打印行,直到以``` 开头的行并将其替换为{{&lt; /terminal &gt;}}。所有其他行正常打印。

    【讨论】:

    • 谢谢!此解决方案没有任何副作用。
    【解决方案4】:

    试试这个:(Nested START END doesn't work and there is no sample/question also)

    $str=~s/((\`\`\`)term)((?:(?!\2).)*)(\2)/\{\{< terminal >\}\}$3\{\{<\/ terminal>\}\}/gs;
    
       ((\`\`\`)term) #  Start match ```term
       ((?:(?!\2).)*)#  Not equal to ```
       (\2)#  End Match```
    

    【讨论】:

      猜你喜欢
      • 2016-05-31
      • 2013-12-26
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      相关资源
      最近更新 更多