#begin command block
#append all lines between two addresses to hold space
sed -n -f - <<\SCRIPT file.xml
\|<tag1>|,\|</tag1>|{ H
#at last line of search block exchange hold and pattern space
\|</tag1>|{ x
#if not conditional ; clear buffer ; branch to script end
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
#do work ; print result; clear buffer ; close blocks
s?*?*?;p;s/.*//;h;b}}
SCRIPT
Jeśli zrobisz powyższe, biorąc pod uwagę wyświetlane dane, przed ostatnim wierszem czyszczenia, powinieneś pracować z sedprzestrzenią wzorów, która wygląda następująco:
^\n<tag1>\n<tag2>foo</tag2>\n</tag1>$
Możesz wydrukować przestrzeń wzoru w dowolnym momencie za pomocą lOOK. Następnie możesz adresować \nznaki.
sed l <file
Pokaże, że każda linia sedprzetwarza ją na etapie, w którym ljest wywoływana.
Właśnie to przetestowałem i potrzebowałem jeszcze jednego \backslashpo ,commapierwszej linii, ale poza tym działa tak, jak jest. Tutaj umieściłem go, _sed_functionaby móc łatwo nazwać go w celach demonstracyjnych w całej tej odpowiedzi: (działa z dołączonymi komentarzami, ale zostały tu usunięte ze względu na zwięzłość)
_sed_function() { sed -n -f /dev/fd/3
} 3<<\SCRIPT <<\FILE
\|<tag1>|,\|</tag1>|{ H
\|</tag1>|{ x
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
s?*?*?;p;s/.*//;h;b}}
#END
SCRIPT
<tag1>
<tag2>bar</tag2>
</tag1>
<tag1>
<tag2>foo</tag2>
</tag1>
FILE
_sed_function
#OUTPUT#
<tag1>
<tag2>foo</tag2>
</tag1>
Teraz zmienimy na pna l, abyśmy mogli zobaczyć, nad czym pracujemy, podczas opracowywania naszego skryptu i usuwania demonstracji non-op, s?dzięki czemu ostatni wiersz naszego sed 3<<\SCRIPTwygląda następująco:
l;s/.*//;h;b}}
Potem uruchomię to jeszcze raz:
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
Ok! Więc miałem rację - to dobre uczucie. Teraz potrząśnij naszym lokiem, aby zobaczyć linie, które wciąga, ale usuwa. Usuniemy nasz obecny li dodamy jeden do, !{block}aby wyglądał następująco:
!{l;s/.*//;h;b}
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
Tak to wygląda tuż przed usunięciem.
Ostatnią rzeczą, którą chcę wam pokazać, jest Hstara przestrzeń, w której ją budujemy. Mam kilka kluczowych pojęć, które, mam nadzieję, mogę wykazać. Więc lponownie usuwam ostatni ook i zmieniam pierwszy wiersz, aby dodać zerknięcie do Hstarej spacji na końcu:
{ H ; x ; l ; x
_sed_function
#OUTPUT#
\n<tag1>$
\n<tag1>\n <tag2>bar</tag2>$
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
\n<tag1>$
\n<tag1>\n <tag2>foo</tag2>$
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
Hstara przestrzeń przetrwa cykle liniowe - stąd nazwa. Więc co ludzie często potknąć się na - Ok, co ja często potknąć się na - jest to, że wymaga kasowania po użyciu. W tym przypadku xzmieniam się tylko raz, więc przestrzeń wstrzymania staje się przestrzenią wzorów i odwrotnie, a ta zmiana przetrwa również cykle linii.
W efekcie muszę usunąć przestrzeń wstrzymania, która była kiedyś przestrzenią wzorów. Robię to, najpierw czyszcząc bieżącą przestrzeń wzorców za pomocą:
s/.*//
Który po prostu wybiera każdą postać i usuwa ją. Nie mogę użyć, dponieważ to skończyłoby mój bieżący cykl linii i następne polecenie nie zostałoby ukończone, co praktycznie zniszczyłoby mój skrypt.
h
Działa to w podobny sposób, Hale zastępuje przestrzeń wstrzymania, więc właśnie skopiowałem swoją pustą przestrzeń wzoru na górze mojej przestrzeni wstrzymania, skutecznie ją usuwając. Teraz mogę po prostu:
b
na zewnątrz.
I tak piszę sedskrypty.