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

15

Использование замещения процесса или группировка & amp; трубопровода, можно передать вывод ( 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)
    
задан Severus Tux 04.10.2016 в 18:29
источник

3 ответа

19

Быстрый ответ. Вы можете использовать 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 ,,}')
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 ,,}')
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 захватывает третье слово.):

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

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

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

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

    
ответ дан Terrance 04.10.2016 в 18:47
источник
17

Вам нужно 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}'
    
ответ дан Matei David 04.10.2016 в 18:43
3

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

В первом примере вы должны использовать:

cat testfile | pee wc "tail -n 5"

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

Ссылка: Ссылка

    
ответ дан T. Verron 05.10.2016 в 07:57