Reputation: 4188
I need to execute a command per line of some file. For example:
file1.txt 100 4
file2.txt 19 8
So my awk
script need to execute something like
command $1 $2 $3
and save the output of command $1 $2 $3
, so system()
will not work and neither will getline
. (I can't pipe the output if I do something like this.)
The restriction to this problem is to use only awk
. (i already had a solution with bashscriot + awk...but I only want awk...just to know more about this)
Upvotes: 4
Views: 3678
Reputation: 364039
Awk's system() function passes the string to /bin/sh, so you can use redirect operators, like ">file.out" if you want.
awk '{system("command " $1 " " $2 " " $3 ">" $1 ".out");}'
Edit: ok, by save, you mean into an awk variable. ephemient is on the right track, then. That's what awk's getline does, like backticks or $(cmd) in shell/perl. In fact, google for awk backticks found this: http://www.omnigroup.com/mailman/archive/macosx-admin/2006-May/054665.html
You say you can't use getline because then you couldn't pipe. But you can work around that with tee and file-descriptor tricks. This works if /bin/sh is bash:
{ "set +o posix; command " $1 " " $2 " " $3 " | tee >(grep foo)" | getline var; print toupper(var); } # bash-only, and broken.
set +o posix
is necessary because awk runs bash as sh
, which makes it go into posix mode after readings its startup files. Hmm, I'm not having any luck getting that to work, and it requires bash anyway.
Ok, this works:
$ touch foo bar
$ echo "foo bar" |
awk '{ "{ ls " $1 " " $2 " " $3 " | tee /dev/fd/10 | grep foo > /dev/tty; } 10>&1" | getline var; print toupper(var); }'
foo
BAR
Upvotes: 0
Reputation: 204688
What's wrong with using getline
?
$ ./test.awk test.txt # ls -F | grep test test.awk* test.txt # cat test.txt | nl 1 ls -F | grep test 2 cat test.txt | nl 3 cat test.awk # cat test.awk #!/usr/bin/awk -f { cmd[NR] = $0 while ($0 | getline line) output[NR] = output[NR] line RS } END { for (i in cmd) print "# " cmd[i] ORS output[i] }
Upvotes: 3