Regex sed替换文本匹配复杂的正则表达式模式

Regex sed替换文本匹配复杂的正则表达式模式,regex,bash,postgresql,sed,gawk,Regex,Bash,Postgresql,Sed,Gawk,我正在将现有的数据库模式移植到Postgresql 我需要用半逗号替换出现的单词“go” 我注意到文本中出现了“go”一词,形式如下: [非空字符串(SQL)] [后跟一个或多个新行] [后跟一个或多个空格] [后接“go”一词] [后跟一个或多个新行] 我想用以下模式替换上述模式: [非空字符串(SQL)] [后跟“;”] [后接两行新词] 我正在尝试构建一个可以与sed一起使用的regex表达式,以执行上面描述的替换-但是我对regex比较陌生 为了清晰起见,我在替换前后加入了示例文

我正在将现有的数据库模式移植到Postgresql

我需要用半逗号替换出现的单词“go”

我注意到文本中出现了“go”一词,形式如下:

  • [非空字符串(SQL)]
  • [后跟一个或多个新行]
  • [后跟一个或多个空格]
  • [后接“go”一词]
  • [后跟一个或多个新行]
我想用以下模式替换上述模式:

  • [非空字符串(SQL)]
  • [后跟“;”]
  • [后接两行新词]
我正在尝试构建一个可以与sed一起使用的regex表达式,以执行上面描述的替换-但是我对regex比较陌生

为了清晰起见,我在替换前后加入了示例文本,我希望实现:

-- Original File contents below -------



go
CREATE TABLE foobar
(
    f1    INT,
    f2    INT,
    f3    FLOAT,
        f4    VARCHAR(32) NOT NULL,
    f5    INT,
    f6    datetime,
        f7    smallint
)


go

GRANT UPDATE, INSERT, DELETE, SELECT ON foobar TO dbusr
go
CREATE UNIQUE INDEX idxu_foobar ON foobar (f1, f2)

go


--- REPLACED FILE CONTENTS -----------



go
CREATE TABLE foobar
(
    f1    INT,
    f2    INT,
    f3    FLOAT,
        f4    VARCHAR(32) NOT NULL,
    f5    INT,
    f6    datetime,
        f7    smallint
);

GRANT UPDATE, INSERT, DELETE, SELECT ON foobar TO dbusr;
CREATE UNIQUE INDEX idxu_foobar ON foobar (f1, f2);
任何人都可以帮助使用表达式来实现这一点,这样我就可以执行:
sed-i的/original\u match\u expr/replacement\u expr/g'myfile.sql

使用的
GNU
版本尝试以下解决方案:

它将整个文件读入一个缓冲区,并用分号替换所有
go
字和它前面的所有空格。它产生:

go
CREATE TABLE foobar
(
    f1    INT,
    f2    INT,
    f3    FLOAT,
        f4    VARCHAR(32) NOT NULL,
    f5    INT,
    f6    datetime,
        f7    smallint
);

GRANT UPDATE, INSERT, DELETE, SELECT ON foobar TO dbusr;
CREATE UNIQUE INDEX idxu_foobar ON foobar (f1, f2);

编辑以添加解释(请参见注释):

这并不像看上去那么难

:a;$!{N;ba}
是一个循环,它将每一行输入读取到缓冲区

[[:space:]
匹配任何空格字符,并将其取反。因此,替换命令将从最后一个非空白字符替换为单词
go
。如果在第一种情况下,go单词前只有空格,则替换不匹配,并且不替换任何内容。


记录分隔符
RS
设置为0个或更多空格字符,后跟
go
。然后,GNU awk将两个连续的记录分隔符实例之间的文本块视为一个记录。因此,打印记录,后跟一个自定义记录分隔符(
后跟两个换行符)

FWIW,只需将单词“go”替换为“;”将生成有效的SQL语句,因为在对Postgresql db(例如“psql-d-U-f”)运行脚本时,换行符和空格通常是不相关的,因为一行代码为+1,但我以前从未使用过awk,请您解释一下表达式中发生了什么?HomunculusReticulli补充了一些解释。+1表示一行代码-但是,这个表达式看起来非常可怕(即使它在我的文件中工作得很好)——我不明白它是如何工作的。请你解释一下这些表达式是如何工作的,这样我就可以从你的例子中学习了?@HomunculusReticulli:用解释更新了答案。谢谢你的解释。我会花时间去读它来理解它。你的答案和1_CR一样好,但我会同意他的答案,因为他先回答,他的解决方案使用sed。谢谢你的帮助,非常感谢。
go
CREATE TABLE foobar
(
    f1    INT,
    f2    INT,
    f3    FLOAT,
        f4    VARCHAR(32) NOT NULL,
    f5    INT,
    f6    datetime,
        f7    smallint
);

GRANT UPDATE, INSERT, DELETE, SELECT ON foobar TO dbusr;
CREATE UNIQUE INDEX idxu_foobar ON foobar (f1, f2);
awk -v RS='\\s*go' '{print $0""(RT ~ /go/? ";\n\n": "")}' file.txt