Aqui está uma versão do script que funciona e corrige algumas coisas que você pode não ter considerado:
#!/bin/bash
(
echo '-- some startup SQL*plus code'
echo 'set echo off;'
echo '-- etc'
find /home/devuser -name 'BI*' -type f |
awk -- '{
gsub("7", "77", $0);
printf("INSERT INTO table1(file_name,status) " \
"VALUES(7%s7, 7N7);\n", $0);
}'
echo 'COMMIT;'
) | sqlplus -s schema_name/passwd
Recursos:
- Seleciona apenas arquivos (
-type f
em find
) que correspondem ao glob 'BI * - veja a página de manual de find(1)
para os diferentes tipos de arquivo disponíveis.
- Escapa nomes de arquivos contendo aspas simples ('→' '), portanto a saída é SQL válida.
7
é o código ASCII octal da aspa simples, útil já que o código awk já está entre aspas simples.
- Mais rápido que a expansão de backtick.
- Deixe de fora a parte
| sqlplus ...
da última linha e você poderá ver o script SQL gerado.
Limitações:
- Não funciona com nomes de arquivos contendo novas linhas ou outros caracteres não imprimíveis.
-
May não funciona com caracteres não-ASCII. Isso depende de vários fatores, alguns no lado do POSIX, alguns no lado do Oracle (e alguns provavelmente dentro do próprio SQL * plus).
- Não é necessariamente o melhor caminho (pessoas melhores irão sem dúvida entrar em sintonia com suas versões).
A seção agrupada no início gera o script, incluindo um prólogo (útil para informar ao SQL * mais o que fazer com alguns dos recursos mais "agradáveis") e um epílogo para confirmar a transação.
O que há de errado com sua própria versão do script:
- As atribuições são assim:
VAR=foo
. Não é VAR = foo
(sim, é importante; o último tentará executar o comando VAR
com argumentos =
e foo
, não executar uma atribuição de variável)
- Se você quiser que
$names
expanda para os resultados do comando find
, será necessário dizer names=$(find ...)
ou names='find ...'
, não names=find ...
.
- Qualquer coisa depois que o
<<EOF
for enviado para o SQL * Plus, o fragmento de script bash incluído (com o for
loop) será interpretado pelo SQL * Plus, não pelo bash. Isso não é SQL válido, e o SQL * Plus naturalmente engasga com isso.
- O corpo do loop
for
é uma instrução SQL, mas você espera que isso seja interpretado pelo bash, o que não está correto. Deve haver um echo
antes da instrução SQL insert
(e, claro, a coisa toda fora da seção <<EOF
).
- Você deixou de fora o
EOF
em si. <<EOF
significa "ler até que uma linha seja encontrada e comece com EOF
".