bash剪切并粘贴SQL插入语句 [英] bash cut and paste SQL insert statement
问题描述
我想从一个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屋!