将 MySQL "INSERT" 命令转换为文本

Convert MySQL "INSERT" commands to text

我正在尝试将最近的维基百科转储导入 MySQL 数据库。问题是,我正在使用 INSERT INTO text MySQL 命令插入 50 GiB text table,我想将它们转换成文本文件。

我的 text.sql 文件具有以下结构:

INSERT INTO text (old_id,old_text,old_flags) VALUES (id1,'text1','flags1'),(id2,'text2','flags2'),...,(idN,'textN','flagsN');

但是,使用 mysql -u USERNAME -p DBNAME < text.sql 非常慢。我已经禁用了 autocommitunique_checksforeign_key_checks,并且我将所有交易封装在一个 START TRANSACTION; ... COMMIT; 块中,但是导入过程仍然很慢。

经过研究,我读到 here 使用 LOAD DATA INFILE; 比使用 INSERT 命令快得多。因此,我希望将 text.sql 转换为 text.txt,如下所示:

id1,'text1','flags1'
id2,'text2','flags2'
...
idN,'textN','flagsN'

我正考虑为此使用 awk,但我在正则表达式方面的经验非常有限。此外,每个 INSERT 命令都在一行中给出,如上所示,这让我更难提取值。

鉴于 text.sql 文件是 50 GiB,您会推荐使用 awk 还是开发一个 C/C++ 程序?如果 awk 是一个好方法,我该如何实现转换?

输入 #1 示例:

INSERT INTO text (old_id,old_text,old_flags) VALUES (id1,'text1','flags1'),(id2,'text2','flags2'),(id3,'text3','flags3');

输出 #1 示例:

id1,'text1','flags1'
id2,'text2','flags2'
id3,'text3','flags3'

输入 #2 示例:(值中有括号)

INSERT INTO page (page_id,page_namespace,page_title,page_restrictions,page_is_redirect,page_is_new,page_random,page_touched,page_latest,page_len,page_content_model) VALUES (10,0,'AccessibleComputing','',1,0,RAND(),DATE_ADD('1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)+0,631144794,69,'wikitext'),(12,0,'Anarchism','',0,0,RAND(),DATE_ADD('1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)+0,703037144,180446,'wikitext');

输出 #2 示例:

10,0,'AccessibleComputing','',1,0,RAND(),DATE_ADD('1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)+0,631144794,69,'wikitext'
12,0,'Anarchism','',0,0,RAND(),DATE_ADD('1970-01-01', INTERVAL UNIX_TIMESTAMP() SECOND)+0,703037144,180446,'wikitext'

输入 #3 示例:(带有转义的 ' 或 ")

INSERT INTO text (old_id,old_text,old_flags) VALUES (631144794,'#REDIRECT [[Computer accessibility]]\n\n{{Redr|move|from CamelCase|up}}','utf-8'),(703037144,'{{Redirect2|Anarchist|Anarchists

|虚构人物|无政府主义者(漫画)|其他用途|无政府主义者(消歧义)}}\n{{pp-move-indef}}\n{{使用英式英语|date=January 2014}}' ,'utf-8');

输出 #3 示例:

631144794,'#REDIRECT [[Computer accessibility]]\n\n{{Redr|move|from CamelCase|up}}','utf-8'
703037144,'{{Redirect2|Anarchist|Anarchists|the fictional character|Anarchist (comics)|other uses|Anarchists (disambiguation)}}\n{{pp-move-indef}}\n{{Use British English|date=January 2014}}','utf-8'

编辑:在进行更多研究后,示例 #2 和 #3 似乎无法使用正则表达式进行转换:来源:#1, #2.

如果这不是您想要的:

$ awk -v FPAT='[(][^)]+[)]' '{for (i=2;i<=NF;i++) print substr($i,2,length($i)-2)}' file
id1,'text1','flags1'
id2,'text2','flags2'
idN,'textN','flagsN'

然后编辑您的问题以提供更清晰、可测试的示例输入和预期输出。

上面为 FPAT 使用了 GNU awk,对于其他 awk,您将使用 while(match()) 循环。

使用这个:

sed -e 's/(//' -e 's/),//' test.csv

(适当的管道)你所有的线路都会干净。

手动更改第一行和最后一行。

此致