Разделить промежуточную трубу на переменную

Рассмотрим следующий пример игрушка (то, что я действительно делаю, более сложно), где я хочу получить две части информации из одной и той же последовательности команд:

echo 'cats pajamas
hatori hanso
batterang
catwoman
fratstar' > tmp1

answer1=$(grep 'cat' tmp1)
answer2=$(grep 'cat' tmp1 | wc -l)

По сути, я ищу способ запустить только более раннюю команду (команды) в последовательности, в данном случае grep, один раз, при этом получая точно те же значения, которые хранятся в переменных answer1 и answer2. Я предполагаю, что это будет работать как разделение канала (так сказать) на answer1 и на wc -l, с выводом последнего на answer2.

Обратите внимание, что использование прерывистой переменной или файла для хранения вывода grep изменит то, что возвращает wc -l. Это мотивирует мой выбор этого игрушечного примера и, я думаю, ограничивает актуальность это. Этот вопрос кажется связанным, однако мне не ясно, как можно присвоить промежуточную часть другой переменной. В настоящее время я нахожусь в bash, хотя можно использовать альтернативные оболочки.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте tee с парой именованных каналов. (Строго говоря, вы могли бы сделать это с одним каналом и стандартным выводом самого grep, но представление проще с двумя каналами.)

mkfifo p1 p2
grep cat tmp1 | tee p1 p2 > /dev/null &
answer1=$(cat p1)
answer2=$(wc -l < p2)

tee разделяет вывод так, как вы хотите, записывая его в два отдельных канала, из которых cat и wc -l считываются независимо позже.

Я предполагаю, что это более применимо к вашему варианту использования, чем answer1=$(grep 'cat' tmp1) и answer2=$(echo "$answer1" | wc -l).

Кажется, что это зависает в строке answer1=..., хотя кажется, что p1 должна была быть открыта для чтения и записи в этот момент... если я добавлю & в конец этой строки, она завершается, однако answer1 кажется пустым. Расследование...

TTT 10.06.2019 20:02

Я решил это, и это работает, как и ожидалось, спасибо. Я думаю, что что-то все еще держалось за fifo. Чтобы надеть на него лук, вы можете пересмотреть свой ответ, чтобы очистить p1 и p2?

TTT 11.06.2019 03:13

Другие вопросы по теме