Adicione dois rev
e troque e
:
echo "string.with.dots" | rev | sed 's/\(.*\)\.\(.*\)/\n/' | rev
Saída:
string with.dots
Considere este comando:
echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)/\n/'
(Combina em um primeiro grupo de captura qualquer caractere até o último .
e em um segundo grupo de captura qualquer caractere depois dele.)
Esta saída:
string.with
dots
Razoavelmente (acho) Eu pensei que usar âncoras na combinação correta teria conseguido reverter esse comportamento (isto é, a correspondência teria sido string
para o primeiro grupo de captura e with.dots
para o segundo grupo de captura), mas:
echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)/\n/'
echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)$/\n/'
echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)$/\n/'
Toda a saída:
string.with
dots
Eu não sei como a correspondência de padrões é implementada, mas parece que sempre privilegia os padrões mais perto do início da string, em vez daqueles que estão mais próximos do final da string (apesar de estarem presentes ^
ou faltando $
).
Como esse comportamento pode ser alterado (ou seja, não como escrever uma solução codificada neste exemplo, mas como reverter a ordem de prioridade de correspondência de padrões em sed
ou em expressões regulares em geral ), se possível?
Adicione dois rev
e troque e
:
echo "string.with.dots" | rev | sed 's/\(.*\)\.\(.*\)/\n/' | rev
Saída:
string with.dots
Para conseguir o que você quer, tente isto:
sed -r 's/^([^.]*)\.(.*)/\n/'
Teste:
$ echo "string.with.dots" | sed -r 's/^([^.]*)\.(.*)/\n/'
string
with.dots
sed
corresponderá com avidez, portanto, enquanto você estiver usando sed 's/\(.*\)\.\(.*\)/\n/'
, ele corresponderá rapidamente ao último .
como o primeiro grupo capturado e depois o restante após o .
como segundo.
Na minha expressão sed
, para impedir que sed
seja ganancioso, tenho que procurar algumas alternativas. Eu combinei desde o início com um .
como o primeiro grupo ( [^.]*
) e depois depois do primeiro jogo como o segundo.
Agora, se você quiser todas as partes em torno de .
em linhas separadas:
$ echo "string.with.dots" | sed -r 's/^([^.]*)\.([^.]*)\.(.*)/\n\n/'
string
with
dots
Gostaria de saber se você pode usar a expansão de parâmetros
$ s="string.with.dots"
$ echo "${s%%.*}"; echo "${s#*.}"
string
with.dots
$ echo "${s%.*}"; echo "${s##*.}"
string.with
dots