Відповіді:
Один з найпростіших способів - не зберігати висновок у змінній, а безпосередньо переглядати її через цикл час / читання.
Щось на зразок:
grep xyz abc.txt | while read -r line ; do
echo "Processing $line"
# your code goes here
done
Існують варіанти цієї схеми залежно від того, що саме ви хочете.
Якщо вам потрібно змінити змінні всередині циклу (і щоб ця зміна була видимою поза нею), ви можете використовувати підстановку процесу, як зазначено у відповіді fedorqui :
while read -r line ; do
echo "Processing $line"
# your code goes here
done < <(grep xyz abc.txt)
while read p || [[ -n $p ]]; do ...
(запозичено з stackoverflow.com/questions/1521462/… )
Ви можете зробити наступний while read
цикл, який подаватиметься за результатами grep
команди, використовуючи так звану підстановку процесу:
while IFS= read -r result
do
#whatever with value $result
done < <(grep "xyz" abc.txt)
Таким чином, вам не потрібно зберігати результат у змінній, а безпосередньо "вводити" його вихід у цикл.
Зверніть увагу на використання IFS=
та read -r
відповідно до рекомендацій у BashFAQ / 001: Як я можу прочитати файл (потік даних, змінний) по черзі (та / або поле за полем)? :
Опція -r для читання перешкоджає інтерпретації зворотної косої риси (зазвичай використовується як пара зворотнього косого кута, щоб продовжуватись через декілька рядків або виходити з розмежувачів). Без цієї опції будь-які незмінені риски на вході будуть відкинуті. Ви майже завжди повинні використовувати параметр -r з читанням.
У вищезазначеному сценарії IFS = запобігає обрізанню пробілу та пробілу. Видаліть його, якщо хочете цього ефекту.
Що стосується заміни процесу, то це пояснюється на сторінці хакерів bash :
Заміна процесу - це форма перенаправлення, де введення чи вихід процесу (деяка послідовність команд) відображаються як тимчасовий файл.
for
версію. Спробував зробити цикл, "${$(grep xyz abc.txt)[@]}"
як у stackoverflow.com/a/14588210/1983854, але не зміг. Тому я просто залишаю першу версію.
zsh
, де такий тип вкладення, ймовірно, працює).
while IFS= read -r result <&3
іdone 3< <(grep ...
Я б запропонував тут використовувати awk замість grep + щось інше.
awk '$0~/xyz/{ //your code goes here}' abc.txt
//your code goes here
?
Без будь-якої ітерації з опцією --line-bupper grep:
your_command | grep --line-buffered "your search"
Приклади реального життя з командою налагодження маршрутизатора Symfony PHP Framework для вимкнення всіх "api" маршрутів:
php bin/console d:r | grep --line-buffered "api"
tail -f some.log
, у моєму випадку) ...
Часто порядок обробки не має значення. Паралель GNU зроблений для цієї ситуації:
grep xyz abc.txt | parallel echo do stuff to {}
Якщо обробка більше схожа на:
grep xyz abc.txt | myprogram_reading_from_stdin
і myprogram
повільно, тоді ви можете запустити:
grep xyz abc.txt | parallel --pipe myprogram_reading_from_stdin
grep -o
такого роду речей.-o
Прапор буде повертати тільки текст , який відповідає, з одного сірника на лінії виходу. (Це не є вичерпним, томуecho aaa |grep 'a*'
дає лише "ааа" та опускає три часткові поєдинки "", "а" та "аа")