Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does (g)awk reverse these lines of output?

So, I'm seeing this output and I'm a bit surprised:

$ echo "a,b,c,d,e,f,g" | cut -d, -f-4
a,b,c,d
$ echo "a,b,c,d,e,f,g" | cut -d, -f6-
f,g
echo "a,b,c,d,e,f,g" | awk '{ print $0 | "cut -d, -f-4"; print $0 | "cut -d, -f6-"; }'
f,g
a,b,c,d

(As a side note, I realize this is a completely silly thing to do in awk, but it's the only command I've seen it happen for!).

As I understand it, this should pipe the record into the two commands -- in order. But for some reason, the output appears reversed. If I do this instead

$ echo "a,b,c,d,e,f,g" | awk '{ print $0 | "echo hello"; print $0 | "echo goodbye"; }'
hello
goodbye

then everything comes in the order I expected. I'm thinking this must be some sort of race condition, but I'm surprised that awk doesn't wait for the subcommand in the pipe to finish. Is this a known issue of using awk or something pecular to gawk? Is there any way to avoid such a pitfall?

EDIT:

I tried it using mawk too... same (reversed) result, and seems to happen consistently for both.

like image 853
FatalError Avatar asked Jan 17 '23 20:01

FatalError


1 Answers

In order to ensure that an external command is completed, you must close the command.

$ echo "a,b,c,d,e,f,g" | awk 'BEGIN {cmd1 = "cut -d, -f-4"; cmd2 = "cut -d, -f6-"} { print $0 | cmd1; close(cmd1); print $0 | cmd2; close(cmd2)}'
a,b,c,d
f,g
like image 103
Dennis Williamson Avatar answered Jan 29 '23 11:01

Dennis Williamson