如何从 SQL 文件中一次提取一个查询?
How to extract one query at a time from an SQL file?
我试图从 SQL 文件中一次提取一个查询。
这是我试过的
index1=1
index2=1
while read -n1 char; do
if [[ $char == ";" ]]
then
SUBSTRING=$(awk 'substr($index1,$index2)' sql1Temp.sql)
echo $SUBSTRING
index1=$index2
fi
((index2+=1))
done <sql1Temp.sql
我的 SQL 文件如下所示:
sql1Temp.sql
select *from test1;
select *from test2;
select *from test3;
我得到的结果是:
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
select *from test1; select *from test2; select *from test3;
select *from test1; select *from test2; select *from test3;
select *from test1; select *from test2; select *from test3;
wedtorque@wedtorque-VirtualBox:~/Desktop$
而我期待的是这样的:
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
select *from test1;
select *from test1;
select *from test1;
wedtorque@wedtorque-VirtualBox:~/Desktop$
另外,当我在 while 循环中回显 $char 时,它会在每次 $char 从查询中获取 * 时打印文件名,select *from test1;等等
像这样
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
s
e
l
e
c
t
masterFile.sh sql1result.sql sql1.sql sql1Temp.sql sql2.sql Untitled Document
f
r
o
m
t
e
s
t
1
select *from test1; select *from test2; select *from test3;
;
same thing 3 times
我认为 awk 有问题吗?
您需要做的只是逐行读取文件,无需 awk
即可完成,而且方法更简单:
while IFS= read -r line; do
echo "$line" # Or do what you need to do (e.g. execute SQL statement)
done <sql1Temp.sql
您不必担心分号,因为 read
语句将一次读取一行,并且每行读取一个语句。
如果你想删除成功执行的语句,你可以这样做:
local statements="sql1Temp.sql"
local failed="sql1Temp.sql.failed"
while IFS= read -r line; do
if
! SOME_SQL_UTILITY "$line"
then
echo "$line" >>"$failed"
fi
done <"$statements"
[[ ! -f "$failed" ]] || mv -f "$failed" "$statements"
本质上,创建一个包含失败语句的新文件,然后移动新文件覆盖旧文件,除非新文件不存在。
请注意! SOME_SQL_UTILITY "$line"
中的!
表示"consider failure of this command as meaning the test succeeds"(本质上是一个非逻辑运算符)。
此外,我在上面的代码中使用了 echo
以使其尽可能熟悉,但使用 printf
可以确保没有特殊字符序列触发意外 shell 行为。将上面的行替换为:
printf "%s" "$line" >>"$failed"
最后,您可以通过使用逻辑运算符而不是 if
块进一步缩短代码:
#!/bin/bash
local statements="sql1Temp.sql"
local failed="sql1Temp.sql.failed"
while IFS= read -r line; do
SOME_SQL_UTILITY "$line" || printf "%s" "$line" >>"$failed"
done <"$statements"
[[ ! -f "$failed" ]] || mv -f "$failed" "$statements"
我还包含了 "shebang" 以允许此脚本作为可执行文件启动。使用逻辑 ||
(OR) 运算符并不比使用 if
语句好,只有当你理解它并且更喜欢它时才这样做。
我试图从 SQL 文件中一次提取一个查询。
这是我试过的
index1=1
index2=1
while read -n1 char; do
if [[ $char == ";" ]]
then
SUBSTRING=$(awk 'substr($index1,$index2)' sql1Temp.sql)
echo $SUBSTRING
index1=$index2
fi
((index2+=1))
done <sql1Temp.sql
我的 SQL 文件如下所示:
sql1Temp.sql
select *from test1;
select *from test2;
select *from test3;
我得到的结果是:
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
select *from test1; select *from test2; select *from test3;
select *from test1; select *from test2; select *from test3;
select *from test1; select *from test2; select *from test3;
wedtorque@wedtorque-VirtualBox:~/Desktop$
而我期待的是这样的:
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
select *from test1;
select *from test1;
select *from test1;
wedtorque@wedtorque-VirtualBox:~/Desktop$
另外,当我在 while 循环中回显 $char 时,它会在每次 $char 从查询中获取 * 时打印文件名,select *from test1;等等
像这样
wedtorque@wedtorque-VirtualBox:~/Desktop$ ./masterFile.sh
s
e
l
e
c
t
masterFile.sh sql1result.sql sql1.sql sql1Temp.sql sql2.sql Untitled Document
f
r
o
m
t
e
s
t
1
select *from test1; select *from test2; select *from test3;
;
same thing 3 times
我认为 awk 有问题吗?
您需要做的只是逐行读取文件,无需 awk
即可完成,而且方法更简单:
while IFS= read -r line; do
echo "$line" # Or do what you need to do (e.g. execute SQL statement)
done <sql1Temp.sql
您不必担心分号,因为 read
语句将一次读取一行,并且每行读取一个语句。
如果你想删除成功执行的语句,你可以这样做:
local statements="sql1Temp.sql"
local failed="sql1Temp.sql.failed"
while IFS= read -r line; do
if
! SOME_SQL_UTILITY "$line"
then
echo "$line" >>"$failed"
fi
done <"$statements"
[[ ! -f "$failed" ]] || mv -f "$failed" "$statements"
本质上,创建一个包含失败语句的新文件,然后移动新文件覆盖旧文件,除非新文件不存在。
请注意! SOME_SQL_UTILITY "$line"
中的!
表示"consider failure of this command as meaning the test succeeds"(本质上是一个非逻辑运算符)。
此外,我在上面的代码中使用了 echo
以使其尽可能熟悉,但使用 printf
可以确保没有特殊字符序列触发意外 shell 行为。将上面的行替换为:
printf "%s" "$line" >>"$failed"
最后,您可以通过使用逻辑运算符而不是 if
块进一步缩短代码:
#!/bin/bash
local statements="sql1Temp.sql"
local failed="sql1Temp.sql.failed"
while IFS= read -r line; do
SOME_SQL_UTILITY "$line" || printf "%s" "$line" >>"$failed"
done <"$statements"
[[ ! -f "$failed" ]] || mv -f "$failed" "$statements"
我还包含了 "shebang" 以允许此脚本作为可执行文件启动。使用逻辑 ||
(OR) 运算符并不比使用 if
语句好,只有当你理解它并且更喜欢它时才这样做。