Search code examples
shelltee

Copy standard input, run two tasks, while reserving the order of output lines?


I want to write a one-line-command to do two tasks with the same copy of stdin. Here is the example:

% echo "Victor\nHugo" | tee >(wc -l) | grep "V"

The result will finally saved into a file, to be processed by my program. And what I expect to get is:

2
Victor

However, sometimes, the order of output might be reversed, if wc happens to be slower:

% echo "Victor\nHugo" | tee >(sleep 1s; wc -l) | grep "V"
Victor
2

Maybe I should not use tee like this? Do you have any suggestions?


Solution

  • You could use a single pipe, with awk:

    printf "Victor\nHugo\n" \
    | awk '{a[NR]=$0} END {print NR; for(i=1;i<=NR;i++) if (a[i]~/^V/) print a[i];}'
    

    It ain't pretty. And it's more memory-hungry the larger your input dataset. But it'll provide the output you expect.