如何在 bash 中编辑多行模式(可使用 sed 和 awk)

如何在 bash 中编辑多行模式(可使用 sed 和 awk)

这是我的具体任务。我有以下类型的模式

.*[class|namespace|struct].*

(准确地说,这是图案的一部分),

然后任意数量的换行符\n或空格混合在一起(可能是 0 个换行符,但至少有 1 个空格),之后我有一个非常具体的模式 - 我基本上知道这一行总是会挡住

{specific_text;^

这是该模式的第二部分。就是这样。

注意:如果存在模式的第一部分,那么肯定存在第二部分。

任务

我需要将每一行替换为相应部分一模式之前的自定义文本,并将其替换为单个花括号和换行符,如下所示 - ''{\n''。

如何使用 bash shell、awk 和 sed 来完成此操作?

注意。因此,您可以看到,基本上我想更改与我的特定模式匹配的第一行,并且它是 class|namespace|struct 关键字之后同类中的第一个。

例子。

class A { specific_text;

转化为

class A {

和这个

class A

{ specific_text;

变成

class A

{

请注意,在最后一个例子中我们保留了换行符。

答案1

sed '/class\|namespace\|struct/ {
   : loop
   s/{ *specific_text;$/{/
   t
   n
   b loop
   }'

它的工作原理如下:

  • 直到找到classnamespace或,它只执行其默认操作:按原样打印传入的行。structsed
  • 当找到class或或namespace时,进入循环。structsed
  • : loop是一个标签,循环的开始。
  • b loop分支到标签,这是循环的结束。
  • 有两种方法可以退出循环:
    • 输入结束,
    • t分支到脚本的末尾。
  • t仅当上述操作s成功时才​​会起作用。
  • 如果t不起作用,脚本将继续n打印当前行并移动到下一行。

换句话说,循环的外部和内部都会打印传入的行,但只有在循环中我们尝试用 进行替换时才会打印s。成功替换后将退出循环。如果遇到另一个classnamespace或 ,该工具将再次循环。struct

换句话说,这正是你想要的(我认为):

更改与我的非常特定的模式匹配的第一行,并且它是 class|namespace|struct 关键字之后同类中的第一个。

笔记:

  • 脚本并不关心class(或namespacestruct)与特定模式之间是什么。
  • 我调整了你的模式。特别是
  • 我在{和之间留有空格,specific_text因为您的测试用例有空格;
  • 我使用了$而不是^,因为^在你的模式中是文字,它没有任何意义(也许你混淆了^$锚点)。

输入示例:

foo
bar
class A {      specific_text;
baz { specific_text;
qux
this is my namespace

whatever
abc {specific_text;
foo
{ specific_text;
{specific_text;

输出:

foo
bar
class A {
baz { specific_text;
qux
this is my namespace

whatever
abc {
foo
{ specific_text;
{specific_text;

修改后的行:

  • class A { specific_text;
  • abc {specific_text;(因为namespace之前有几行)

相关内容