2010-05-04 18 views
15

Tengo una cadena multilínea procedente de otro programa que quiero convertir a un comando SQL. Yo esperaba que printf me podría ayudar, pero no parece funcionar:Formato stdin en bash

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

que estaba esperando para ver:

 
SELECT '1 
2 
3' INTO MyTable 

Pero tengo:

 
SELECT INTO MyTable 

Cómo ¿Puedo obtener el% s para leer stdin?

Respuesta

24

Use xargs para transformar entrada estándar a los argumentos del programa:

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

Sabía que había una manera. Estaba mirando a Xargs también pero no pude armarlo todo. Esto es exactamente lo que quería. – User1

+0

Esto funcionaría bien, excepto que el printf de bash no es el mismo que el ejecutable/usr/bin/printf, lo que significa que no puede usar "% q". Fui con el comando funcional de @Dennis Williamson – isaaclw

2

No puede. El comando printf cáscara formatea sus argumentos no entrada estándar así que lo que puede hacer es proporcionar la salida de un comando como un solo argumento:

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

Editar: una solución en 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 Dejaré de desnudar la nueva línea final como un ejercicio para el lector. Si quieres hacer algo más complejo en el printf, entonces tendrás que crear un guión awk más creativo.

+0

¿Hay otro comando que podría funcionar en el orden propuesto en la pregunta? – User1

+0

Es posible que pueda acercarse al simple uso de 'printf' en su ejemplo con' awk'. Lo agregaré a mi respuesta. –

+0

@ User1, hay un poco de precedente en el comando * xargs *. Toma datos de stdin y ejecuta comandos con los datos divididos en múltiples argumentos en un comando "plantilla". Puede escribir un pequeño programa de shell (por ejemplo, llamado * 1args *) como 's =" $ (cat) ";" $ @ "" $ s "' y usarlo como 'printf '% s \ n' 1 2 3 | 1args printf "SELECCIONE '% s' INTO MyTable \ n" 'para mantener su orden. Pero no estoy muy convencido de su utilidad. Existe un límite para el tamaño de los argumentos (difiere según el sistema operativo), que limitará la cantidad de argumentos que puede incluir en un argumento. –

5

seguirlo:

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

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