将大型MySQL转储文件转换为CSV格式

5

我尝试了类似于这样的操作

awk -F " " '{if($1=="INSERT"){print $5}}' input.sql | \
    sed -e "s/^(//g" -e "s/),(/\n/g" -e "s/['\"]//g" \
        -e "s/);$//g" -e "s/,/;/g" > output.txt

但我发现它很慢且未经优化

MySQL转储文件的外观如下

CREATE TABLE MyTable{
    data_1,
    data_2
};

INSERT INTO MyTAble VALUES ('data_1','data_2'),...,('data_1','data_2');
INSERT INTO MyTAble VALUES ('data_1','data_2'),...,('data_1','data_2');
...
INSERT INTO MyTAble VALUES ('data_1','data_2'),...,('data_1','data_2');

我的目标是获得以下结果的文件(不用'或"来包装字段):
data_1,data_2
data_1,data_2
...
data_1,data_2

提前感谢您!


你的意思是 data_1 就像带有双引号或单引号的 "some data" 吗? - Håkon Hægland
你是说 data_1, data_2 类似于 'data_1, data_2' 吗? - Håkon Hægland
抱歉,我编辑了一下,我的“...”可能让你误解了... 我需要每行中出现的N个(data_1,data_2)对,而不仅仅是第一个... 是我的错误。 - Syffys
好的,看看我的更新...这样对你有用吗? - Håkon Hægland
每个 Couple 周围总是有单引号吗?例如 ('abc,def') - Håkon Hægland
每个数据元素内部可以有逗号吗?例如 ('abc,xf','gg') - Håkon Hægland
2个回答

1
您可以尝试:

gawk '/^INSERT/ {
    match ($0,/[^(]*\(([^)]*)\)/,a)
    print a[1]
}' input.sql

* 更新 *

再次阅读问题后,也许这更符合您的要求:

/^INSERT/ {
    line=$0
    while (match (line,/[^(]*\(([^)]*)\)/,a)) {
        cur=a[1]
        sub(/^['"]/,"",cur)
        sub(/['"]$/,"",cur)
        print cur
        line=substr(line,RSTART+RLENGTH)
    }
}

* 更新2 *

根据问题的最新更新,这里是一个新版本:

/^INSERT/ {
    line=$0
    while (match (line,/[^(]*\(([^)]*)\)/,a)) {
        line=substr(line,RSTART+RLENGTH)
        match(a[1],/'([^']*)','([^']*)'/,b)
        print b[1]
        print b[2]
    }
}

当我尝试在单行上执行它时: gawk '/^INSERT/ {line=$0;while (match (line,/[^(](([^)]))/,a)){;cur=a[1];sub(/^['"]/,"",cur);sub(/['"]$/,"",cur);print cur;line=substr(line,RSTART+RLENGTH)}}' input.sql 我得到了以下结果:-bash: syntax error near unexpected token `)' 可能需要转义一些引号? - Syffys
@Syffys 好的,试着把 awk 脚本放在一个名为 f.awk 的文件中,然后执行 awk -f f.awk input.sql - Håkon Hægland
谢谢,现在它确实可以工作了!但是,它似乎比我之前的命令慢得多... - Syffys
@Syffys 是的,你说得对,这个版本大约比你原来的慢了一半。我会尝试制作一个更快的版本。 - Håkon Hægland
@Syffys 我试图让它更快,但我失败了... 我猜原因可能是 substrmatch 或两者结合使用。 - Håkon Hægland

1
sed -n "/.*INSERT INTO MyTAble VALUES (\([^)]*\)).*/ {
   s/.*INSERT INTO MyTAble VALUES \(.*\);/\1/
   s/(\([^)]*\)),*/\\1\\
/g
   s/'//g
   s/\\n$//
   p
   }" input.sql > output.sql

基于您的(新)样本。

1
抱歉,就像我所说的那样,我的 ... 可能误导了您,我已更新了我的示例。谢谢! - Syffys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接