Как передать выходные данные одной команды нескольким командам?
Используя подстановку процесса или группировку и конвейер, можно передать вывод (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
как другие ответы.
Получить только начальную и конечную части файла:
[wolf]$ cat >foo
1
2
3
4
5
6
^d
[wolf]$ cat foo | tee >(head -2) >(tail -2) >/dev/null
1
2
5
6