使用 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
,将 awk
的 RS
变量设置为 \nCREATE[^)]*\n\);
以仅获取所示示例中的必需部分。然后在主程序中检查条件,如果 RT 不为 NULL,则从中删除开始行和结束行并打印它,以便只从 sql 的输出中获取需要的部分。
我正在尝试从如下所示的 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
,将 awk
的 RS
变量设置为 \nCREATE[^)]*\n\);
以仅获取所示示例中的必需部分。然后在主程序中检查条件,如果 RT 不为 NULL,则从中删除开始行和结束行并打印它,以便只从 sql 的输出中获取需要的部分。