#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 sed
przestrzenią 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ą l
OOK. Następnie możesz adresować \n
znaki.
sed l <file
Pokaże, że każda linia sed
przetwarza ją na etapie, w którym l
jest wywoływana.
Właśnie to przetestowałem i potrzebowałem jeszcze jednego \backslash
po ,comma
pierwszej linii, ale poza tym działa tak, jak jest. Tutaj umieściłem go, _sed_function
aby 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 p
na 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<<\SCRIPT
wyglą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 l
okiem, aby zobaczyć linie, które wciąga, ale usuwa. Usuniemy nasz obecny l
i 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 H
stara przestrzeń, w której ją budujemy. Mam kilka kluczowych pojęć, które, mam nadzieję, mogę wykazać. Więc l
ponownie usuwam ostatni ook i zmieniam pierwszy wiersz, aby dodać zerknięcie do H
starej 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>$
H
stara 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 x
zmieniam 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ć, d
ponieważ 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, H
ale 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ę sed
skrypty.