将 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
非常慢。我已经禁用了 autocommit
、unique_checks
和 foreign_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
(适当的管道)你所有的线路都会干净。
手动更改第一行和最后一行。
此致
我正在尝试将最近的维基百科转储导入 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
非常慢。我已经禁用了 autocommit
、unique_checks
和 foreign_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
(适当的管道)你所有的线路都会干净。
手动更改第一行和最后一行。
此致