2010-05-04 8 views
15

J'ai une chaîne multiligne provenant d'un autre programme que je veux convertir en commande SQL. J'espérais que printf pouvait me aider, mais il ne semble pas fonctionner:Format stdin dans bash

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

J'espérais voir

 
SELECT '1 
2 
3' INTO MyTable 

Mais je suis:

 
SELECT INTO MyTable 

Comment puis-je obtenir le% s pour lire stdin?

Répondre

24

Utilisez xargs pour transformer stdin pour programmer des arguments:

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

Je savais qu'il y avait un moyen. Je regardais aussi xargs mais je n'arrivais pas à l'assembler. C'est exactement ce que je voulais. – User1

+0

Cela fonctionnerait bien, sauf que printf de bash n'est pas identique à l'exécutable/usr/bin/printf, ce qui signifie que vous ne pouvez pas utiliser "% q". Je suis allé avec la commande fonctionnelle de @ William Williamson – isaaclw

2

Vous ne pouvez pas. La commande shell printf formats ses arguments pas l'entrée standard donc ce que vous pouvez faire est de fournir la sortie d'une commande comme un seul argument:

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

Modifier: une solution dans 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 Laissera dépouiller la nouvelle ligne finale comme un exercice pour le lecteur. Si vous voulez faire quelque chose de plus complexe dans le printf, alors vous devrez trouver un script awk plus créatif.

+0

Y at-il une autre commande qui pourrait fonctionner dans l'ordre proposé dans la question? – User1

+0

Vous pourriez vous rapprocher de la simple utilisation de 'printf' dans votre exemple avec' awk'. Je vais l'ajouter à ma réponse. –

+0

@ User1, Il y a un peu de précédent dans la commande * xargs *. Il prend les données de stdin et exécute les commandes avec les données divisées en plusieurs arguments en une commande "template". Vous pouvez écrire un petit programme shell (par exemple appelé * 1args *) comme 's =" $ (cat) ";" $ @ "" $ s "' et l'utiliser comme 'printf '% s \ n' 1 2 3 | 1args printf "SELECT '% s' DANS MATE \ n" 'pour maintenir votre commande. Mais je ne suis pas convaincu de son utilité. Il y a une limite à la taille des arguments (diffère par OS), cela limitera la quantité de stdin que vous pourriez ajouter dans un argument. –

5

pour cette solution:

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

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