Mam kilka wierszy pobranych z pliku po uruchomieniu polecenia grep w następujący sposób:
var=`grep xyz abc.txt`
Powiedzmy, że mam 10 linii, które w rezultacie składają się z xyz.
Teraz muszę przetworzyć każdą linię, którą otrzymałem w wyniku polecenia grep. Jak mam to zrobić?
grep -o
tego rodzaju rzeczy.-o
Flaga będzie oddać tylko tekst, który odpowiada z jednego meczu na linię produkcji. (Nie jest wyczerpująca, więcecho aaa |grep 'a*'
podaje tylko „aaa” i pomija trzy częściowe dopasowania „”, „a” i „aa”)Odpowiedzi:
Jednym z łatwych sposobów nie jest przechowywanie danych wyjściowych w zmiennej, ale bezpośrednie iterowanie po nich za pomocą pętli while / read.
Coś jak:
Istnieją różnice w tym schemacie w zależności od tego, czego dokładnie szukasz.
Jeśli chcesz zmienić zmienne wewnątrz pętli (i chcesz, aby ta zmiana była widoczna poza nią), możesz użyć podstawiania procesów zgodnie z odpowiedzią fedorqui :
źródło
while read p || [[ -n $p ]]; do ...
(zapożyczone ze stackoverflow.com/questions/1521462/… )Możesz wykonać następującą
while read
pętlę, która będzie zasilana wynikiemgrep
komendy z wykorzystaniem tzw. Podstawienia procesu:W ten sposób nie musisz przechowywać wyniku w zmiennej, ale bezpośrednio „wstrzyknąć” jej wyjście do pętli.
Zwróć uwagę na użycie
IFS=
iread -r
zgodnie z zaleceniami w BashFAQ / 001: Jak odczytać plik (strumień danych, zmienną) wiersz po wierszu (i / lub pole po polu)? :Jeśli chodzi o zastępowanie procesu, jest to wyjaśnione na stronie hakerów bash :
źródło
for
wersję. Próbowałem wykonać pętlę,"${$(grep xyz abc.txt)[@]}"
jak na stackoverflow.com/a/14588210/1983854, ale nie udało się. Zostawiam więc tylko pierwszą wersję.zsh
, gdzie ten rodzaj zagnieżdżenia prawdopodobnie działa).while IFS= read -r result <&3
idone 3< <(grep ...
Sugerowałbym użycie awk zamiast grep + coś innego tutaj.
awk '$0~/xyz/{ //your code goes here}' abc.txt
źródło
//your code goes here
?Bez żadnej iteracji z opcją grep --line-buffered:
Przykład z życia wzięty z wyprowadzeniem polecenia debugowania routera w Symfony PHP Framework w celu grepowania wszystkich tras związanych z „api”:
źródło
tail -f some.log
w moim przypadku) ...Często kolejność przetwarzania nie ma znaczenia. GNU Parallel jest stworzone dla tej sytuacji:
Jeśli przetwarzanie bardziej przypomina:
i
myprogram
jest powolny, możesz biec:źródło
Powtarzaj wyniki grep za pomocą pętli while / read. Lubić:
źródło
Dla tych, którzy szukają jednowierszowego:
źródło