bash剪切并粘贴SQL插入语句 [英] bash cut and paste SQL insert statement

查看:119
本文介绍了bash剪切并粘贴SQL插入语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个INSERT语句中删除一个列名值对,并将其移入另一个INSERT语句。我有大约100个具有这种格式的单独文件(尽管格式可能会因文件而有所不同,例如某些用户可能已将整个INSERT语句放在一行中)。



输入

  INSERT INTO table1(
col1,
col2

VALUES(
foo,
bar
);

INSERT INTO table2(
col3,
col4_move_this_one,
col5

VALUES(
john,
doe_move_this_value,
doe
);

OUTPUT

  INSERT INTO table1(
col1,
col4_move_this_one,
col2

VALUES(
foo,
doe_move_this_value,
bar
);

INSERT INTO table2(
col3,
col5

VALUES(
john,
doe
) ;

与上述格式一般,我想我可以在脚本中使用sed和cat来查找行每行的数字被移动,然后移动它,像这样。

 
line_number = $(cat -n $ {file} | sed some_statement | awk to_get_line_number)
#etc ...
完成

...但也许你们可以推荐一种更聪明的方法,如果INSERT语句位于同一行上,也可以使用。


GNU awk适用于真正的多维数组,第三个参数匹配(),多字符RS和\ s / \ S语法糖:

解决方案

/ p>

  $ cat tst.awk 
BEGIN {RS =\\s *); \\s *}
match($ 0,/(\ S + \ s +){2}([^(] +)[(]([^)] +)[)] [^(] + [( ]([^)] +)/,a){
for(i in a){
gsub(/ ^ \ s * | \s * $ /,,a [i ])
gsub(/ \ s * \\\
\s * /,,a [i])
}
表格[NR] = a [2]
名称[NR] [1]; split(a [3],名称[NR],/,/)
值[NR] [1]; split(a [4],值[NR], / $ / $)

END {
names [1] [3] = names [1] [2]
names [1] [2] = names [2] [2]
名字[2] [2] =名字[2] [3]
删除名称[2] [3]

值[1] [3] =值[1] [2]
值[1] [2] =值[2] [2]
values [2] [2] = values [2] [3]
删除值[2] [3]

for(tableNr = 1; tableNr< = NR; (nr = 1; nr <= cnt)tableNr ++){
printfINSERT INTO%s(\ n,tables [tableNr]
cnt = length(names [tableNr])
; nr ++){
printnames [tableNr] [nr](nr }
print)

打印VALUES(
cnt = length(values [tableNr])
(nr = 1; nr <= cnt; nr ++){
printvalues [tableNr] [nr ](nr }
print); \\\

}
}

  $ awk -f tst。 awk文件
INSERT INTO表1(
col1,
col4_move_this_one,
col2

VALUES(
foo,
doe_move_this_value,
bar
);

INSERT INTO table2(
col3,
col5

VALUES(
john,
doe
) ;


I would like to remove a column name value pair from one INSERT statement and move it into another INSERT statement. I have about a hundred seperate files that have this sort of format (although the format may vary slightly from file to file, for instance some users may have put the entire INSERT statement on one line).

INPUT

INSERT INTO table1 (
    col1,
    col2
)
VALUES (
    foo,
    bar
);

INSERT INTO table2 (
    col3,
    col4_move_this_one,
    col5
)
VALUES (
    john,
    doe_move_this_value,
    doe
);

OUTPUT

INSERT INTO table1 (
    col1,
    col4_move_this_one,
    col2
)
VALUES (
    foo,
    doe_move_this_value,
    bar
);

INSERT INTO table2 (
    col3,
    col5
)
VALUES (
    john,
    doe
);

In general with the above format I was thinking I could use sed and cat in a script to find line numbers of each line to be moved and then move it, something like this.

for file in *; do
    line_number=$(cat -n ${file} | sed some_statement | awk to_get_line_number)
    # etc...
done

...but maybe you guys can recommend a more clever way that would work also if the INSERT statement is on one line.

解决方案

With GNU awk for true multi-dimensional arrays, 3rd arg to match(), multi-char RS and \s/\S syntactic sugar:

$ cat tst.awk
BEGIN { RS="\\s*);\\s*" }
match($0,/(\S+\s+){2}([^(]+)[(]([^)]+)[)][^(]+[(]([^)]+)/,a) {
    for (i in a) {
        gsub(/^\s*|\s*$/,"",a[i])
        gsub(/\s*\n\s*/,"",a[i])
    }
    tables[NR] = a[2]
    names[NR][1]; split(a[3],names[NR],/,/)
    values[NR][1]; split(a[4],values[NR],/,/)
}
END {
    names[1][3] = names[1][2]
    names[1][2] = names[2][2]
    names[2][2] = names[2][3]
    delete names[2][3]

    values[1][3] = values[1][2]
    values[1][2] = values[2][2]
    values[2][2] = values[2][3]
    delete values[2][3]

    for (tableNr=1; tableNr<=NR; tableNr++) {
        printf "INSERT INTO %s (\n", tables[tableNr]
        cnt = length(names[tableNr])
        for (nr=1; nr<=cnt; nr++) {
            print "    " names[tableNr][nr] (nr<cnt ? "," : "")
        }
        print ")"

        print "VALUES ("
        cnt = length(values[tableNr])
        for (nr=1; nr<=cnt; nr++) {
            print "    " values[tableNr][nr] (nr<cnt ? "," : "")
        }
        print ");\n"
    }
}

.

$ awk -f tst.awk file
INSERT INTO table1 (
    col1,
    col4_move_this_one,
    col2
)
VALUES (
    foo,
    doe_move_this_value,
    bar
);

INSERT INTO table2 (
    col3,
    col5
)
VALUES (
    john,
    doe
);

这篇关于bash剪切并粘贴SQL插入语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆