我有一个postgresql数据库转储,它是由pgïu dump版本9.5.2实现的,其中包含DDL和 INSERT INTO
给定数据库中每个表的语句。转储如下所示:
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
转储文件非常大,而且是由另一家公司生成的,因此我无法影响导出过程。我需要从这个转储创建2个文件:
所有ddl语句(所有不以 INSERT INTO
)
全部 INSERT INTO important_table
语句(我只想从dump还原一些表)
如果所有语句都是单行的,数据中没有换行符,那么grep创建2个sql脚本就非常容易了,例如:
grep -v '^INSERT INTO .*;$' my_dump.sql > ddl.sql
grep -o '^INSERT INTO important_table .*;$' my_dump.sql > important_table.sql
# Create empty structures
psql < ddl.sql
# Import only one table for now
psql < important_table.sql
首先我想用 grep
但我没有发现,如何一次处理多行,于是我尝试了 sed
但它只返回单行插入。我也用过https://regex101.com/ 找到正确的正则表达式,但我不知道如何将它与 grep
或者 sed
:
^(?!(INSERT INTO)).*$ -- for ddl
^INSERT INTO important_table(\s|[[:alnum:]])*;$ -- for inserts
我发现类似的问题pcregrep多行sql匹配,但没有答案。另外,我也不介意这个解决方案是否适用于 grep
, sed
或者你的建议,但它应该在ubuntu18.04.4tls上工作。
1条答案
按热度按时间kupeojn61#
下面是一个基于bash的解决方案
perl
一行程序,为后续的grep
声明。在我的方法中,目标是通过我调用的脚本在一行中获得一条sql语句
prepare.sh
. 它变得有点复杂,因为我想在insert数据字符串中容纳分号和引号(这些以及换行符在中间输出中由十六进制代码表示):编辑:为了回应@32cupo的评论,下面是一组修改过的脚本,可以避免
xargs
对于大数据集(尽管我没有大的转储文件来测试它):然后,一个单独的脚本(称为
ddl.sh
)包括您的grep
语句(并且在循环的帮助下,只将较小的块(行)馈送到xarg中):另一个单独的脚本(称为
important_table.sh
)包括您的grep
插入到重要表中的语句:下面是一组正在运行的脚本(请注意,我用一些分号和引号为insert数据添加了香料):