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 ".