tags:

views:

62

answers:

3

I have a multi-line string coming from another program that I want to convert to a SQL command. I was hoping that printf could help me, but it doesn't seem to work:

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

I was hoping to see:

SELECT '1
2
3' INTO MyTable

But I got:

SELECT  INTO MyTable

How can I get the %s to read stdin?

+1  A: 

You can't. The printf shell command formats its arguments not standard input so what you can do is provide the output of a command as a single argument:

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

Edit: a solution 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'll leave stripping the final newline as an exercise to the reader. If you want to do anything more complex in the printf, then you will have to come up with some more creative awk script.

D.Shawley
Is there another command that could work in the order proposed in the question?
User1
You might be able to get close to the simple `printf` usage in your example with `awk`. I'll add it to my answer.
D.Shawley
@User1, There is a bit of precedent in the *xargs* command. It takes data from stdin and runs commands with the data broken into multiple arguments to a “template” command. You could write a small shell program (e.g. called *1args*) like `s="$(cat)";"$@" "$s"` and use it as `printf '%s\n' 1 2 3 | 1args printf "SELECT '%s' INTO MyTable\n"` to maintain your order. But I am not quite convinced as to its utility. There is a limit to the size of arguments (differs per OS), that will limit how much stdin you might stuff into an argument.
Chris Johnsen
A: 

Give this a try:

printf_stdin() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }

echo -e '1\n2\n3' | printf_stdin 'SELECT %s INTO MyTable'
Dennis Williamson
+1  A: 

Use xargs to transform stdin to program arguments:

echo -n  -e '1\n2\n3' |xargs -0  printf 'SELECT %s INTO MyTable'
Jürgen Hötzel
I knew there was a way. I was just looking at xargs too but couldn't quite piece it together. This is exactly what I wanted.
User1