在pgdump中匹配多行SQL语句
我有pg_dump 9.5.2版的PostgreSQL数据库转储,其中包含DDL,还包含给定数据库中每个表的在pgdump中匹配多行SQL语句,sql,regex,postgresql,sed,grep,Sql,Regex,Postgresql,Sed,Grep,我有pg_dump 9.5.2版的PostgreSQL数据库转储,其中包含DDL,还包含给定数据库中每个表的INSERT-INTO语句。转储看起来像这样: SET语句\u超时=0; 设置锁定超时=0; 设置客户端_编码='UTF8'; 创建不重要的表( id整数不为空, col1字符变化 ); 创建表( id整数不为空, col2字符不为空, 不重要的字符不为空 ); 插入不重要的_表值(123456,'一些数据拆分为 -多重 -线条 只是为了好玩); 插入重要的_表值(987654321,'一
INSERT-INTO
语句。转储看起来像这样:
SET语句\u超时=0;
设置锁定超时=0;
设置客户端_编码='UTF8';
创建不重要的表(
id整数不为空,
col1字符变化
);
创建表(
id整数不为空,
col2字符不为空,
不重要的字符不为空
);
插入不重要的_表值(123456,'一些数据拆分为
-多重
-线条
只是为了好玩);
插入重要的_表值(987654321,'一些重要数据','另一个垃圾拆分为
-行“);
...
--两个表中都有数千个插入项
转储文件非常大,并且是由另一家公司生成的,因此我无法影响导出过程。我需要从此转储创建2个文件:
开头的语句插入到)
插入到重要的\u表中语句(我只想从转储恢复一些表)
grep-v'^INSERT-in.*;$'my_dump.sql>ddl.sql
grep-o“^INSERT到重要表中。*;$”my_dump.sql>重要_table.sql
#创建空结构
psql
首先,我考虑使用grep
,但我没有发现如何一次处理多行,然后我尝试了sed
,但它只返回单行插入。我也曾经找到正确的正则表达式,但我不知道如何将它与grep
或sed
结合起来:
^(?(插入)).*--ddl
^插入到重要的_表(\s |[:alnum:])*;$--用于插入
我发现了类似的问题,但没有答案。另外,我不介意该解决方案是否可以与grep
、sed
或您建议的任何东西一起使用,但它应该可以在ubuntu18.04.4tls上使用。下面是一个基于bash的解决方案,它使用perl
一行程序为后续grep
语句准备SQL转储数据。在我的方法中,目标是通过我称为
prepare.sh
的脚本在一行上获取一条SQL语句。它变得有点复杂,因为我想在插入数据字符串中容纳分号和引号(这些以及换行符在中间输出中由十六进制代码表示):编辑:为了回应@32cupo的评论,下面是一组经过修改的脚本,它避免了使用大数据集进行
xargs
(尽管我没有大的转储文件来测试):然后,一个单独的脚本(称为
ddl.sh
)包含ddl的grep
语句(并且在循环的帮助下,只将较小的块(行)馈送到XARG中):下面是一组正在运行的脚本(请注意,我用一些分号和引号添加了插入数据):
谢谢你的回答。当我在您的示例中尝试您的代码时,它起作用了,当我在截断的转储中执行它时,但当我在我的转储(9GB,16GB)中尝试它时,它只创建空文件。我试图只运行
cat large-dump.sql |/prepare.sh
,但它什么也不输出。似乎我使用的虚拟机内存不足,无法进行转储,因此我将尝试使用更大的虚拟机,并让您知道。在虚拟机调整大小后,xargs:argument line太长
。你能建议任何改变吗,如何省略xargs?你好@32cupo,我明白了。9GB-16GB是压倒性的xargs。我将检查是否有不同的方法。@32cupo,我已经编辑了答案以提供一组修改过的脚本。
#!/bin/bash
perl -pne 's/;(?=\s*$)/__ENDOFSTATEMENT__/g' \
| perl -pne 's/\\/\\\\x5c/g' \
| perl -pne 's/\n/\\\\x0a/g' \
| perl -pne 's/"/\\\\x22/g' \
| perl -pne 's/'\''/\\\\x27/g' \
| perl -pne 's/__ENDOFSTATEMENT__/;\n/g' \
#!/bin/bash
while read -r line; do
<<<"$line" xargs -I{} echo -e "{}"
done < <(grep -viE '^(\\\\x0a)*insert into')
#!/bin/bash
while read -r line; do
<<<"$line" xargs -I{} echo -e "{}"
done < <(grep -iE '^(\\\\x0a)*insert into important_table')
~/$ cat dump.sql
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
CREATE TABLE unimportant_table (
id integer NOT NULL,
col1 character varying
);
CREATE TABLE important_table (
id integer NOT NULL,
col2 character varying NOT NULL,
unimportant_col character varying NOT NULL
);
INSERT INTO unimportant_table VALUES (123456, 'some data split into
- multiple
- lines
;just for fun');
INSERT INTO important_table VALUES (987654321, 'some important ";data"', 'another crap split into
- lines;');
...
-- thousands of inserts into both tables
~/$ cat dump.sql | ./prepare.sh | ./ddl.sh >ddl.sql
~/$ cat ddl.sql
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
CREATE TABLE unimportant_table (
id integer NOT NULL,
col1 character varying
);
CREATE TABLE important_table (
id integer NOT NULL,
col2 character varying NOT NULL,
unimportant_col character varying NOT NULL
);
...
-- thousands of inserts into both tables
~/$ cat dump.sql | ./prepare.sh | ./important_table.sh > important_table.sql
~/$ cat important_table.sql
INSERT INTO important_table VALUES (987654321, 'some important ";data"', 'another crap split into
- lines;');