Mylą mnie dwie koncepcje sed: trzymaj przestrzeń i przestrzeń wzorców. Czy ktoś może pomóc je wyjaśnić?
Oto fragment instrukcji:
h H Copy/append pattern space to hold space. g G Copy/append hold space to pattern space. n N Read/append the next line of input into the pattern space.
Te sześć poleceń naprawdę mnie zmyliło.
echo $'1\n2\n3\n4' | sed -n '1~2h;2~2{p;x;p}'
info sed
. Jest znacznie bardziej szczegółowy niż sama strona podręcznika.Odpowiedzi:
Kiedy sed czyta pliku linia po linii, linia, która została obecnie odczytać jest włożona do wzorca bufora (wzór przestrzeni). Bufor wzorców jest jak tymczasowy bufor, notatnik, w którym przechowywane są bieżące informacje. Kiedy każesz sedowi wydrukować, wypisuje bufor wzorca.
Hold buffer / hold space jest jak przechowywanie długoterminowe, tak że możesz coś złapać, zapisać i ponownie użyć później, gdy sed przetwarza kolejną linię. Nie przetwarzasz bezpośrednio przestrzeni do przechowywania, zamiast tego musisz ją skopiować lub dołączyć do przestrzeni wzoru, jeśli chcesz coś z nią zrobić. Na przykład polecenie print
p
drukuje tylko obszar wzoru. Podobnies
działa na przestrzeni wzorców.Oto przykład:
(opcja -n wyłącza automatyczne drukowanie linii)
Istnieją trzy komendy tutaj:
1!G
,h
i$p
.1!G
ma adres1
(pierwsza linia), ale!
oznacza, że polecenie zostanie wykonane wszędzie z wyjątkiem pierwszej linii.$p
z drugiej strony zostanie wykonany tylko w ostatniej linii. A więc co się dzieje:h
kopiuje pierwszą linię do przestrzeni ładunkowej .G
, dołączając zawartość bufora wstrzymującego do bufora wzorców, oddzielając ją znakiem nowej linii. Przestrzeń wzoru zawiera teraz drugą linię, nową linię i pierwszą linię.h
polecenie wstawia połączoną zawartość bufora wzorców do przestrzeni wstrzymania, która teraz zawiera odwrócone wiersze dwa i jeden.Na koniec, po przeczytaniu ostatniej linii i dołączeniu do przestrzeni wzoru miejsca przechowywania (zawierającego wszystkie poprzednie wiersze w odwrotnej kolejności), wypisywany jest znak
p
. Jak się domyślasz, powyższe robi dokładnie to samo, cotac
polecenie - wyświetla plik w odwrotnej kolejności.źródło
'195,210{/add/p}'
… Czy można wyodrębnić ostatnią linię z grupy linii wchodzących w skład wzorca?@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.
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:wyjście wygląda następująco:
(Zauważ, że
Host: foo1
na wyjściu pojawia się dwukrotnie).Wyjaśnienie:
-n
wyłącza wyjście, chyba że zostanie wyraźnie wydrukowaneHost:
linię w buforze wstrzymania (h)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.
źródło
grep 'Host\|Info'
awk
odpowiednik twojego kodu seda też jest dość krótki:awk '/Host:/{hold=$0}; /Info/{print hold; print;}' myfile.txt
Chociaż odpowiedź @ January i przykład są fajne, wyjaśnienie nie było dla mnie wystarczające. Musiałem wiele szukać i się uczyć, zanim udało mi się zrozumieć, jak dokładnie
sed -n '1!G;h;$p'
działa. Chciałbym więc rozwinąć polecenie dla kogoś takiego jak ja.Przede wszystkim zobaczmy, co robi polecenie.
Odwraca dane wejściowe, tak jak
tac
robi to polecenie.sed
czyta wiersz po wierszu, więc zobaczmy, co się dzieje w przestrzeni wzorcowej i przestrzeni wstrzymania w każdym wierszu. Ponieważh
polecenie kopiuje zawartość przestrzeni wzoru do przestrzeni przechowywania, obie przestrzenie mają ten sam tekst.W ostatnim wierszu
$p
wypisujed\nc\nb\na$
formatowany doJeśli chcesz zobaczyć przestrzeń wzoru dla każdej linii, możesz dodać
l
polecenie.Uważam, że bardzo pomocne jest obejrzenie tego samouczka wideo Zrozumienie, jak działa sed , ponieważ facet pokazuje krok po kroku, jak każda przestrzeń będzie używana. Odstępy między uchwytami są omówione w czwartym samouczku, ale polecam obejrzenie wszystkich filmów, jeśli nie jesteś zaznajomiony
sed
.Również dokument GNU sed i tutorial Bruce'a Barnetta Sed są bardzo dobrymi odniesieniami.
źródło