使用 grep 捕获组正则表达式

Capturing group regex with grep

我正在尝试从如下所示的 PostgreSQL 模式转储中捕获 SQL DDL“CREATE”:

SET default_table_access_method = heap;

CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);

ALTER TABLE schema_name.table_name OWNER TO user;

CREATE INDEX index ON schema_name.table_name USING btree (col1);

我想要的是:

CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);`

为什么 grep -Po "(CREATE TABLE)[\S\s]*(;)" dump.sql 不起作用?

PCRE2 /CREATE TABLE [\w]*\.[\w]*[\S\s]*(;)/U 匹配正确。

谢谢。

sed 将是更好的工具:

sed -n '/^CREATE TABLE/,/;$/p' file.sql

CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);

如果您真的想要 gnu-grep 解决方案,请使用:

grep -zPo "(?m)^CREATE TABLE[^;]+;\R" file.sql

CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);

不确定你的正则表达式,但这有效:

grep -Poz "CREATE TABLE[^;]*;" dump.sql

给出:

CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);

因为它被标记为 perl...这是一个快速脚本,使用我发现的一个旧的但漂亮的模块,SQL::Script,来解析 SQL 转储:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use SQL::Script; # Install with your favorite CPAN client

# Pass the dump file name as the command-line argument

my $script = SQL::Script->new;
$script->read($ARGV[0]);
foreach my $stmt ($script->statements) {
    say "$stmt;" if $stmt =~ /^CREATE TABLE/i;
}

示例:

$ ./dump_tables test.sql
CREATE TABLE schema_name.table_name (
    col1 bigint,
    col2 text
);

使用 GNU awk 你可以尝试下面的 awk 程序。

awk -v RS='\nCREATE[^)]*\n\);' 'RT{gsub(/(^|$)\n/,"",RT);print RT}' Input_file

解释: 使用 GNU awk,将 awkRS 变量设置为 \nCREATE[^)]*\n\); 以仅获取所示示例中的必需部分。然后在主程序中检查条件,如果 RT 不为 NULL,则从中删除开始行和结束行并打印它,以便只从 sql 的输出中获取需要的部分。