Portál AbcLinuxu, 11. května 2025 07:07
Jde jen o příklad, ale potreboval bych z tohodle:
ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN
dostat toto: ABC_MN ABC_MN
Došel jsem k tomuto:
echo ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN | \
sed 's/ABC\([^M][^N]\)\+MN/ABC_MN/g'
ale nefunguje to...
ABC…MN
, mezi kterými je alespoň jedna dvojice písmen, přičemž v té dvojici vždy první písmeno nesmí být M
a druhé N
. Takže třeba pokud bude mezi ABC
a MN
lichý počet znaků, nebude vám to fungovat. Zkuste místo toho \([^M][^N]\)\+
použít .\+?
– pokud tuhle konstrukci váš sed
umí. +?
je v Perl-like syntaxy „ne-nenasytný“ (ungreedy) operátor, tj. „spolkne“ co nejméně znaků.
Ale možná by nebylo od věci popsat, co chcete udělat doopravdy, možná bude existovat nějaké plně jiné jednoduché řešení. Ten váš příklad totiž nedává žádný smysl.
A nešlo by to větším kladivem?
echo ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN | perl -pe 's/ABC.+?NM/ABC_NM/g;'
dává
ABC_NM A AB AC BC BA CA CB MN ABC_NM A AB MN
A co takhle?
Prepinac -r pro sed tam je pro pouziti rozsirenych reg. vyrazu. Bez nej to neprojde.
echo "ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN" | sed -r 's/ABC(M[^MN]|[^M])*MM*N/ABC_MN/g'
Děkuji vsem za reakce...
Mě jde o to jake pomocí regulárního výrazu udělat něco jako [^ ] pronekolik znaků, tedy aby se například nemohlo v textu vyskytnout ABC ale mohlo A AB BC AC...
Něco jako [^\(ABC\)]
toto: echo ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN | perl -pe 's/ABC.+?NM/ABC_NM/g;'
je přesnš to co hledám...
Díky moc
Jenom pro zajímavost... Jak by se to udělalo bez tech Perl-like vychytávek?
S tou negaci toho ABC, neslo by to takhle?: ([^A][^\ ]*)|(A^B[^\ ]*)|(AB^C[^\ ]*)
Nevim, jestli mam spravne syntaxi, protoze je to uz chvilka, co jsem si naposledy nejak poradne s regexpy hral, ale jde zhruba o to, ze bud bereme slova, ktera zacinaji na cokoliv jineho nez A, nebo (kdyz uz na A zacinaji) alespon nemaji na druhem miste B a nebo na tretim C.
Hmm, tak odbornik taky nejsem, ale ve skole jsme se ucili, jak jdou regularni vyrazy prevadet na konecne automaty a verim, ze to nejak podobne spousta enginu i dela. Slozitost toho prevodu je myslim i linearni, ale moc se mi nad tim ted premyslet nechce :) Takze na ten regexp, co jsem predtim napsal, by stacily tri konecne automaty, ktere by to prochazelo paralelne a navic, kdyz by to v jednom z nich prestalo odpovidat, tak se muze cela ta jedna vetev prestat resit (neco jako zkracene vyhodnocovani logickych operaci). Fakt nevim, jak jsou ty enginy delany, ale verim, ze s timhle by nemely nejmensi problem.
sed
u a všem možném je ten, že nejde o regulární výrazy ve smyslu teorie formálních jazyků m/A(?!BC)/
Na urovni POSIX-regexpu tento ukol neni jednoduchy.
echo ABC M N NM A AB AC BC BA CA CB MN ABC M BC BA CA CB N NM A AB MN | sed 's/ABC\(AB[^C]\|A[^B]\|[^A]\)\+MN/ABC_MN/g'
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.