Скопировать стандартный ввод, выполнить две задачи, сохранив порядок строк вывода?

Я хочу написать однострочную команду для выполнения двух задач с одной и той же копией стандартного ввода. Вот пример:

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

Результат будет окончательно сохранен в файл, который будет обработан моей программой. И что я ожидаю получить это:

2
Victor

Однако иногда порядок вывода может быть обратным, если wc бывает медленнее:

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

Может быть, я не должен использовать tee как это? У вас есть какие-нибудь предложения?

2 ответа

Решение

Вы можете использовать одну трубу с 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];}'

Это не красиво. И чем больше памяти, тем больше ваш входной набор данных. Но это даст ожидаемый результат.

Для этого примера я думаю, что самый ясный подход - классический преоцедурный стиль:

names="Victor\nHugo\n"
printf $names | wc -l
printf $names | grep "V"
Другие вопросы по тегам