Как передать выходные данные одной команды нескольким командам?

Используя подстановку процесса или группировку и конвейер, можно передать вывод (stdout) набор команд в качестве ввода для другой команды.

Пример:

wc < <(echo hi;echo bye)
(echo hi; bye) | wc

Но есть ли обратное?

То есть есть ли способ отправить вывод одной команды в качестве ввода для многих других команд в одной строке?

Что-то вроде:

cat testfile | wc | tail -n 5

(Не воспринимайте трубопроводы буквально) . Здесь я пытаюсь передать вывод cat testfile как для wc а также tail -n 5

Другой пример будет:

(чтобы получить последнее слово в предложении)

echo "some random words"| wc -c | cut -f(out put of wc -c) (output of first echo)

4 ответа

Решение

Быстрый ответ. Ты можешь использовать tee >(what_to_do) >(another_thing_to_do) продолжать идти с вашей командой столько разных вещей, которые вы хотите сделать.

Пример:

Исходный тестовый файл вывода:

:~$ cat testfile.txt 
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616

Выход с tee добавлены команды:

:~$ cat testfile.txt | tee >(tail -1) >(wc) >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
      2      10      91
Serial Number:    TW0XFJWX550854187616

Каждая команда в tee - это просто обычные команды, которые вы используете в командной строке, например, добавить в >(head -1 | wc) работает так же.

:~$ cat testfile.txt | tee >(tail -1) >(head -1 | wc)  >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
      1       7      52
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
Serial Number:    TW0XFJWX550854187616

Или вы можете также взять последнее слово, скажем, последнюю строку, используя awk с $NF с wc а также вот так:

:~$ cat testfile.txt | tail -1 | tee >(wc) >(awk '{print $NF}')
Serial Number:    TW0XFJWX550854187616
TW0XFJWX550854187616
      1       3      39

ПРИМЕЧАНИЕ. Добавление | Команда pipe до конца может быть отменена с помощью нескольких команд из tee команда. У меня есть несколько примеров, которые я тестировал:

Пример 1 (команда Pipe извлекает все последние слова):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $NF}'
words
24
5
1

Пример 2 (Не показывает вывод команд wc. Команда pipe захватывает 3-е слово.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $3}'
just

Пример 3 (Захват 3-го слова в строке эха. Команда Tee.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $3}')
This is just five words
just
24
5
1

Пример 4 (Получение последнего слова в строке эха. Команда Tee.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $NF}')
This is just five words
words
24
5
1

Надеюсь это поможет!

Тебе нужно tee разделить поток на части. Пытаться:

cat testfile | tee >(wc -l) >(wc -w) >(wc -c) | tail -n 5

Заметки:

  • Если несколько процессов (wc, tail) все пишем в stdout:

    • Вы можете получить искаженный вывод.

    • Нет никакой гарантии в том порядке, в котором они появятся. Чтобы увидеть это, попробуйте sleep 1; wc -w как второй потребитель.

  • tee заблокирует, если какой-либо из его пунктов назначения не потребляет поток достаточно быстро. Это означает, что получатели будут получать ввод с примерно одинаковой скоростью (по модулю буферизации фиксированного размера). Это не легко исправить, единственная альтернатива - сохранить поток в файл и раздать его потребителям отдельно. За wc а также tail это не проблема.

Для последнего слова проще сделать:

echo "some random words" | awk '{print $NF}'

moreutils пакет предоставляет команду pee (Слияние труб и тройник, что вы думаете?), что делает именно это.

Для первого примера вы бы использовали:

cat testfile | pee wc "tail -n 5"

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

Ссылка: https://joeyh.name/code/moreutils/

Получить только начальную и конечную части файла:

      [wolf]$ cat >foo
1
2
3
4
5
6
^d
[wolf]$ cat foo | tee >(head -2) >(tail -2) >/dev/null
1
2
5
6
Другие вопросы по тегам