从 MySQL 转储中提取 CREATE TABLE 定义?

Extracting CREATE TABLE definitions from MySQL dump?

我有一个超过 1 TB 的 MySQL 转储文件。我需要从中提取 CREATE TABLE 语句,以便提供 table 定义。

我购买了 Hex Editor Neo,但我有点失望。我创建了一个正则表达式 CREATE\s+TABLE(.|\s)*?(?=ENGINE=InnoDB) 来提取 CREATE TABLE 子句,这似乎在 NotePad++ 中运行良好。

但是,提取所有实例的预计到达时间超过 3 小时,我什至无法确定它是否正确执行。我什至不知道这些行完成后是否可以导出。

有没有一种快速的方法可以在我的 Ubuntu 盒子上使用 grep 或其他方法来完成此操作?

更新

运行 这一夜,输出文件变成了空白。我创建了一个较小的数据子集,但该过程仍然无法正常工作。然而,它在正则表达式测试器中工作,但 grep 不喜欢它并产生空输出。这是我 运行 的命令。我会提供样品,但我不想为我的客户泄露机密。这只是一个标准的 MySQL 转储。

grep -oP "CREATE\s+TABLE(.|\s)+?(?=ENGINE=InnoDB)" test.txt > plates_schema.txt

更新 它似乎与 CREATE\s+TABLE 部分之后的新行不匹配。

您可以使用以下内容:

grep -ioP "^CREATE\s+TABLE[\s\S]*?(?=ENGINE=InnoDB)" file.txt > output.txt

知道了! grep 不支持跨多行匹配。我找到了 this question helpul 并且最终改用 pcregrep。

pcregrep -M "CREATE\s+TABLE(.|\n|\s)+?(?=ENGINE=InnoDB)" test.txt > plates.schema.txt

您可以使用 Perl 来完成此任务...这应该非常快。

Perl 的 ..(范围)运算符是有状态的 - 它会记住求值之间的状态。 它的意思是:如果您对 table 的定义以 CREATE TABLE 开头并以 ENGINE=InnoDB DEFAULT CHARSET=utf8; 之类的内容结尾,那么下面将执行您想要的操作。

perl -ne 'print if /CREATE TABLE/../ENGINE=InnoDB/' INPUT_FILE.sql > OUTPUT_FILE.sql

编辑:

由于您正在处理一个非常大的文件并且可能想知道进度,pv 也可以为您提供:

pv INPUT_FILE.sql | perl -ne 'print if /CREATE TABLE/../ENGINE=InnoDB/' > OUTPUT_FILE.sql

这会显示进度条、速度和预计到达时间。

如果可以再次运行 mysqldump,只需添加--no-data