2010-05-04 9 views
15

Ho una stringa multi-riga proveniente da un altro programma che voglio convertire in un comando SQL. Speravo che printf mi potrebbe aiutare, ma non sembra funzionare:Formato stdin in bash

 
echo -e '1\n2\n3'|printf 'SELECT %s INTO MyTable' 

speravo di vedere:

 
SELECT '1 
2 
3' INTO MyTable 

Ma ho ottenuto:

 
SELECT INTO MyTable 

Come posso ottenere% s per leggere lo stdin?

risposta

24

Utilizzare xargs di trasformare stdin programmare argomenti:

echo -n -e '1\n2\n3' |xargs -0 printf 'SELECT %s INTO MyTable' 
+0

Sapevo che c'era un modo. Stavo solo guardando xargs ma non riuscivo a metterlo insieme. Questo è esattamente quello che volevo. – User1

+0

Funzionerebbe bene, ad eccezione del fatto che bash's printf non è lo stesso dell'eseguibile/usr/bin/printf, il che significa che non puoi usare "% q". Sono andato con il comando funzionale di @Dennis Williamson – isaaclw

2

Non è possibile. Il comando printf shell formatta i suoi argomenti non standard input così che cosa si può fare è fornire l'output di un comando come un unico argomento:

bash$ printf "SELECT '%s' INTO MyTable" "`echo -e '1\n2\n3'`" 
SELECT '1 
2 
3' INTO MyTable 
bash$ 

Edit: una soluzione in Awk

bash$ echo -e '1\n2\n3' | awk -v 'ORS=' ' 
    BEGIN { print "SELECT \"" } 
    { print $0, "\n" } 
    END { print "\" INTO MyTable" }' 
SELECT "1 
2 
3 
" INTO MyTable 
bash$ 

I lascerò togliere al newline la finale finale come un esercizio. Se vuoi fare qualcosa di più complesso nello printf, allora dovrai inventare qualche altro script awk creativo.

+0

C'è un altro comando che potrebbe funzionare nell'ordine proposto nella questione? – User1

+0

Potrebbe essere possibile avvicinarsi al semplice uso di 'printf' nell'esempio con' awk'. Lo aggiungerò alla mia risposta. –

+0

@ User1, C'è un po 'di precedente nel comando * xargs *. Prende i dati da stdin ed esegue i comandi con i dati suddivisi in più argomenti in un comando "modello". Potresti scrivere un piccolo programma di shell (ad esempio chiamato * 1args *) come 's =" $ (cat) ";" $ @ "" $ s "' e usarlo come 'printf '% s \ n' 1 2 3 | 1args printf "SELEZIONA% s" INTO MyTable \ n "' per mantenere l'ordine. Ma non sono abbastanza convinto della sua utilità. C'è un limite alla dimensione degli argomenti (differisce per OS), che limiterà quanto stdin si possa inserire in un argomento. –

5

dare una prova:

printf_stdin() { local stdin; read -d '' -u 0 stdin; printf "[email protected]" "$stdin"; } 

echo -e '1\n2\n3' | printf_stdin 'SELECT %s INTO MyTable'