Answers:
这是有效的脚本版本,可修复您可能没有考虑的一些问题:
#!/bin/bash
(
echo '-- some startup SQL*plus code'
echo 'set echo off;'
echo '-- etc'
find /home/devuser -name 'BI*' -type f |
awk -- '{
gsub("\047", "\047\047", $0);
printf("INSERT INTO table1(file_name,status) " \
"VALUES(\047%s\047, \047N\047);\n", $0);
}'
echo 'COMMIT;'
) | sqlplus -s schema_name/passwd
特征:
-type f
中find
)-有关find(1)
可用的不同文件类型,请参见手册页。\047
是单引号的八进制ASCII码,非常有用,因为awk代码已经在单引号内。| sqlplus ...
最后一行的部分,您可以看到生成的SQL脚本。局限性:
开头的分组部分将生成脚本,包括一个序言(用于告诉SQL * plus如何使用其“更精细”的功能)和一个结语以提交事务。
您自己的脚本版本有什么问题:
VAR=foo
。不VAR = foo
(是的,它的事项;后者将尝试运行命令VAR
与参数=
和foo
,不执行变量赋值)$names
扩展到find
命令的结果,则需要说names=$(find ...)
或names=`find ...`
,而不是names=find ...
。<<EOF
都会发送到SQL * Plus,因此,您所包含的bash脚本片段(与for
循环一起)是由SQL * Plus而不是bash解释的。那不是有效的SQL,SQL * Plus自然会使其窒息。for
循环的主体是一个SQL语句,但是您希望它由bash解释,这是不对的。echo
SQL insert
语句之前应该有一个(当然,本<<EOF
节中的所有内容)。EOF
本身。<<EOF
表示“读到遇到以EOF
' 开头的行。for VARIABLE in 1 2 3 4 5 .. N
do
command1
command2
commandN
done <<anything given here is taken as variable>>
这是基本语法,在之后的done
提交应在下一行给出。
所以你的代码应该是。
#!/bin/bash
names = find /home/devuser -name 'BI*'
sqlplus -s schema_name/passwd << EOF
for name in {names[@]}
do
insert into table1(file_name,status) values('$name','N');
done
commit;
exit