pipes, redirects and awk -v
June 15, 2008
I wanted to take the output of a command and put it in a temporary variable so I can append a string to it. (Trying to script perforce to append something to my client spec without interactive involvement.)
First attempt:
$ p4 client -o > $CLIENTSPEC
c:cygwinbinbash: $CLIENTSPEC: ambiguous redirect
I later learned that redirect is only for files.
Next attempt:
$ TEST=p4 client -o
$ echo $TEST
//depot/apps/diamond-calendar-preview/… //sallen-LENOVO/svn/openlaszlo/branches/pagan-deities/diamond-calen //depot/apps/diamond-amaranth-ms2/… //sallen-LENOVO/svn/openlaszlo/branches/pagan-deities/diamond-amaranth- //depot/sandbox/my-webtops/… //sallen-LENOVO/svn/openlaszlo/branches/wafflecone/diamond/client/my-webtops/. ..
which seems to have swallowed line endings and only provided the last few lines of output.
My colleagues at Laszlo, Trebor Fenstermaker and Chris Pettitt and ptw, showed me the error of my ways and provided some good tips. Trebor noted that there is a length limit for shell variables and that line endings will get lost. Chris introduced a combination of pipe and awk -v which did the trick. At first I thought Tucker’s simple echo solution wasn’t working, but he pointed out that I just needed to properly parenthesize my commands.
What worked:
p4 client -o | awk -v append=” //depot/apps/test/… //sallen-test/svn/openlaszlo/branches/pagan-deities/test/…” ‘{ print $0 } END { print append }’ | p4 client -i
Even simpler:
(p4 client -o; echo ” //depot/apps/test/… //sallen-test/svn/openlaszlo/branches/pagan-deities/test/…” ) | p4 client -i
Notes:
-
Redirect only works for files, there are lots of different types of redirects (> is a simple redirect of stdout to a file, >> will append to a file, 2> will redirect stderr)
-
awk -v will define a variable which can then be used in the awk script
-
You need to properly parenthesize your commands: ( p4 client -o; echo “Thing to append” ) | p4 client -i
The parens will execute the p4 and echo commands in a sub-shell so the output of both will be piped to the next. Without the parens you have said:
p4 client -o; ( echo “Thing to append” | p4 client -i )
I.e., run the client command, then run echo to a pipe.
-
Pipe will let you take the stdout of one command and send it to the stdin of another: