Redirecting Output of print to multiples files in awk

You can not do it with awk.

Using tee, you can do something like this:

$ awk '{print ID[i]" "Value[i]" "TS1[i]" "TS2[i]}' file | tee out1 out2

Using tee -a if you want to append instead of override existed files.

If you don't want to print the whole output, you can try:

awk '
    BEGIN {outfile["a.txt"];outfile["b.txt"]}
    { for (file in outfile) { print > file } }' file

Within awk, instead of redirecting to a file with print "text" > "file", you can redirect to a command using:

print "something" | "tee file1.txt file2.txt"

The first time you use that |, awk spawns the command, and the next time it reuses the same command, so it doesn't start a new tee each time you do that and doesn't overwrite the files (you need to call close("tee file1.txt file2.txt") if you do want awk to start a new command the next time). However, if you do both > "file1.txt" and | "tee file1.txt..." there will be a conflict.

You may then want to use >> "file1.txt" and | "tee -a file1.txt..." instead.

However, I'd still go with @cuonglm's for approach or use an awk function as that would be cleaner and more efficient.


A user defined function might make your code cleaner and cause less duplication, if that's what the concern is.

function print_to_files( message, file_a, file_b ) {
   print message > file_a;
   print message > file_b;
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message , "filea", "fileb" );'

Or hard code the files if that's all you need.

function print_to_files( message ) {
   print message > "/path/to/filea";
   print message > "/path/to/fileb";
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message );'