@Ed Morton: Nie zgadzam się z tobą tutaj. Znalazłem sed
bardzo przydatne i proste (kiedy już poznasz koncepcję wzorca i trzymasz bufory), aby wymyślić elegancki sposób wykonywania greppingu wielowierszowego.
Na przykład weźmy plik tekstowy, który zawiera nazwy hostów i kilka informacji o każdym hoście, z mnóstwem śmieci pomiędzy nimi, o które nie dbam.
Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Dla mnie skrypt awk, który po prostu pobrałby wiersze z nazwą hosta i odpowiadającą im info
linią, zająłby trochę więcej niż to, co jestem w stanie zrobić z sedem:
sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt
wyjście wygląda następująco:
Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!
(Zauważ, że Host: foo1
na wyjściu pojawia się dwukrotnie).
Wyjaśnienie:
-n
wyłącza wyjście, chyba że zostanie wyraźnie wydrukowane
- pierwsze dopasowanie, wyszukuje i umieszcza
Host:
linię w buforze wstrzymania (h)
- drugie dopasowanie, znajduje następną linię Info:, ale najpierw zamienia (x) bieżącą linię w buforze wzorca z buforem wstrzymującym i drukuje (p)
Host:
linię, następnie ponownie zamienia (x) i drukuje (p) linię Info:.
Tak, to jest uproszczony przykład, ale podejrzewam, że jest to powszechny problem, który został szybko rozwiązany przez prosty jednowierszowy sed. W przypadku dużo bardziej złożonych zadań, takich jak te, w których nie można polegać na danej, przewidywalnej sekwencji, awk może być lepiej dopasowany.
echo $'1\n2\n3\n4' | sed -n '1~2h;2~2{p;x;p}'