Acho que entendi agora - obrigado .
Com regexp estendido para manipular os opcionais para os caracteres extras em N um pouco mais fácil (note que a entrada de exemplo usada aqui é ligeiramente diferente da sua na pergunta) :
sed -Ee's|([sio=%]..)?([@!T()^$/].)? *||g' \
<<""
:
$ $ $N
$ $ $a
sa s l r
*56 l r
o1 o 2
%%xv
:
$ $ $N
$ $ $a
sa s lr
*56lr
o1 o 2
%%xv
Você precisará de um GNU / BSD / AST sed
para usar isso. Um BRE equivalente seria como:
sed 's|\([soi=%]..\)\{0,1\}\([@!T()^$/].\)\{0,1\} *||g'
O truque é fazer com que todas as combinações sejam opcionais, de modo que nenhuma parte de um padrão tenha precedência. Como você está realmente removendo dados - e não inserindo (que teria que ser tratado de forma muito diferente) você não terá problemas com as correspondências para sequências nulas no intervalo entre suas metas de correspondência . Quem se importa quantas seqüências de caracteres nulas são removidas?
A regex de sed
verifica o espaço padrão globalmente e da esquerda para a direita. Se houvesse alguma possibilidade de sobreposição entre as correspondências, isso não funcionaria muito bem, porque não recua em g
lobal. Mas há apenas um caso em que posso pensar e é tratado aqui. De qualquer forma, o espaço está sempre do lado direito, e há sempre algum espaço não à esquerda. É possível, no entanto, que N possa ser um dos delims únicos que você nomeou, mas nesse caso o espaço ainda é preservado como deveria ser.
Conforme ele varre, verifica a entrada em relação aos padrões - o primeiro que pode corresponder é o de 3 caracteres, o segundo é o de 2 caracteres e o terceiro é um único - um espaço (embora essa correspondência possa continue por qualquer extensão) .
Quando algum deles for encontrado, sed
irá substituir uma das duas primeiras correspondências por si mesma - como a páscoa -, mas a terceira será removida completamente. E de uma só vez.