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

StackOverflow https://stackoverflow.com/questions/13972430

  •  11-12-2021
  •  | 
  •  

質問

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?

役に立ちましたか?

解決

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.

他のヒント

For this example I think the clearest approach is classic preocedural style:

names="Victor\nHugo\n"
printf $names | wc -l
printf $names | grep "V"
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top