Przenośnym sposobem na to - i bardziej wydajnym - są adresy. Możesz to zrobić:
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
W ten sposób, jeśli linia nie zawiera ciąg kota i nie zawiera łańcuch pies sed
b
Rancza z skryptu autoprints obecną linię i ciągnie w następnym, aby rozpocząć kolejny cykl. Dlatego nie wykonuje następnej instrukcji - która w tym przykładzie c
ustawia całą linię do czytania Niedźwiedzia, ale może zrobić wszystko.
Prawdopodobnie warto również zauważyć, że każda instrukcja występująca po !b
tym sed
poleceniu może pasować tylko do wiersza zawierającego ciąg dog
lub cat
- dzięki czemu można wykonywać dalsze testy bez niebezpieczeństwa dopasowania wiersza, który tego nie robi - co oznacza, że można teraz zastosować reguły tylko do jednego lub drugiego.
Ale to jest następne. Oto dane wyjściowe powyższego polecenia:
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Możesz także przenośnie zaimplementować tabelę odnośników z referencjami wstecznymi.
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x
};G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'
Konfiguracja tego prostego przykładowego przypadku wymaga dużo więcej pracy, ale sed
na dłuższą metę może zapewnić znacznie bardziej elastyczne skrypty.
W pierwszej linii I e x
zmiana miejsca przechowywania i wzór przestrzeni następnie włóż ciąg <space>
kota <space>
psa<space>
do miejsca przechowywania przed e x
zmieniającym je z powrotem.
Odtąd i na każdej kolejnej linii G
trzymam spację dołączoną do spacji wzoru, a następnie sprawdzam, czy wszystkie znaki od początku linii do nowej linii, którą właśnie dodałem na końcu, pasują do ciągu otoczonego spacjami po niej. Jeśli tak, to zamieniam całą partię na Niedźwiedzia, a jeśli nie, to nic złego się nie dzieje, ponieważ następnie P
rintuję tylko do pierwszej nowej linii w przestrzeni wzorów, a następnie d
usuwam wszystko.
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
A kiedy mówię „elastyczny”, mam na myśli to. Tutaj zastępuje kota z BrownBear, a psa z BlackBear :
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x
};G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'
###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear
Oczywiście możesz znacznie rozszerzyć zawartość tabeli odnośników - podniosłem ten pomysł z e-maili usenetowych Grega Ubbena na ten temat, kiedy w latach 90. opisał, jak zbudował prymitywny kalkulator na podstawie jednej sed s///
instrukcji.
-r
opcję jako synonim-E
dla kompatybilności z GNU sed. OpenBSD i OS Xsed -E
będą interpretować ucieczkę potoku jako literał potoku, a nie jako operator przemiany. Oto działający link do strony podręcznika NetBSD, a tutaj jest jeden dla OpenBSD, który nie ma dziesięciu lat.