1

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

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

我注意到“go”这个词出现在文本中,模式如下:

  • [非空字符串 (SQL)]
  • [后跟一个或多个新行]
  • [后跟一个或多个空格]
  • [后面跟着“去”这个词]
  • [后跟一个或多个新行]

我想用以下模式替换上述模式:

  • [非空字符串 (SQL)]
  • [其次是 ';']
  • [后跟两条新线]

我正在尝试构建一个可以与 sed 一起使用的正则表达式,以执行上述替换 - 但我对正则表达式相对较新。

为了清楚起见,我在我想要实现的替换之前和之后包含了示例文本:

-- 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 's/original_match_expr/replacement_expr/g' myfile.sql

4

2 回答 2

1

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

sed -ne ':a; $! { N; ba }; s/\([^[:space:]]\)[[:space:]]*go/\1;/g; p' infile

它将整个文件读入缓冲区,并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:]]匹配任何空白字符并将[^[:space:]]其取反。所以替换命令从最后一个非空白字符替换到单词go。如果在第一种情况下单词之前只有空格go,则替换不匹配并且不会替换任何内容。

于 2013-11-02T20:18:42.610 回答
1

呆呆

awk -v RS='\\s*go' '{print $0""(RT ~ /go/? ";\n\n": "")}' file.txt

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

于 2013-11-02T20:21:46.480 回答