sed, wzorce niepasujące

Mam losowy łańcuch znaków, w którym interesuje mnie pewien element. Potrafię opisać go wyrażeniem regularnym.
Jak teraz usunąć wszystko to, co nie pasuje do wyrażenia?
Załóżmy, że interesuje mnie foo:
echo losowyłańcuchfoobarshmoo | sed 's/foo//’
usunie foo, podczas gdy ja chcę, by tylko foo pozostało. Kombinowałem
trochę z !, ale nie wiem jak to zastosować.


sed 's/.*\(foo\).*/\1/’
To się chyba „backreferences” nazywa. Bierzesz coś w nawiasy \(…\),
a potem się możesz do tego odwoływać przez \1, \2 itp., w zależności o którą parę nawiasów Ci chodzi (można poszatkować regexp na kawałki, usunąć wybrane fragmenty, zamienić ich kolejność, zduplikować je itp.). Np załóżmy, że masz listę wierszy w postaci:
a=b+c
a chcesz je pozamieniać na
a-c=b
więc robisz 's/\(.*\)=\(.*\)+\(.*\)/\1-\3=\2/g’
Działa cacy. Albo inny przykład – chcesz wygenerować szybki indeks html
mając tylko płaski spis plików (np. wynik „ls”).
track01.cdda.ogg
track02.cdda.ogg
track03.cdda.ogg
track04.cdda.ogg
track05.cdda.ogg
track06.cdda.ogg
Więc można to przepuścić przez:
's/^\(.*\)\.cdda\.ogg$/<a href=”&”>\1<\/a>/g’
i już masz spis html-owych odnośników, z odciętymi rozszerzeniami.


Jesteś tego absolutnie pewien? Skąd to przeświadczenie, że wszyscy używają Extended RE? Mój sed na przykład standardowo pracuje w trybie Basic RE i jeśli zastosowałbym się do Twoich „poprawek”, to wszystko bym popsuł.