Suponha que eu tenha a string 'abbc' e queira substituir:
- ab -> bc
- bc -> ab
Se eu tentar duas substituições, o resultado não é o que eu quero:
echo 'abbc' | sed 's/ab/bc/g;s/bc/ab/g'
abab
Então, qual comando sed posso usar para substituir como abaixo?
echo abbc | sed SED_COMMAND
bcab
Edição : Na verdade, o texto pode ter mais de 2 padrões e não sei quantas substituições vou precisar. Como houve uma resposta dizendo que sed
é um editor de fluxo e suas substituições são avidamente, acho que precisarei usar alguma linguagem de script para isso.
g
bandeira de ambos oss///
comandos e isso funcionará.ab
oubc
na entrada original.Respostas:
Talvez algo parecido com isto:
Substitua
~
por um caractere que você sabe que não estará na string.fonte
\x0
-lo~~
.g
necessário e o que faz?g
é para global - ele substitui todas as instâncias do padrão em cada linha, em vez de apenas a primeira (que é o comportamento padrão).Eu sempre uso várias instruções com "-e"
$ sed -e 's:AND:\n&:g' -e 's:GROUP BY:\n&:g' -e 's:UNION:\n&:g' -e 's:FROM:\n&:g' file > readable.sql
Isso acrescentará um '\ n' antes de todos os AND, GROUP BY, UNION e FROM, enquanto '&' significa a string correspondente e '\ n &' significa que você deseja substituir a string correspondente por um '\ n' antes do 'correspondente "
fonte
Aqui está uma variação da resposta de ooga que funciona para várias pesquisas e substitui pares sem precisar verificar como os valores podem ser reutilizados:
Aqui está um exemplo:
antes:
depois de:
Observe que
\b
denota limites de palavras, o que evita que________
interfira na pesquisa (estou usando o GNU sed 4.2.2 no Ubuntu). Se você não estiver usando uma pesquisa de limite de palavras, essa técnica poderá não funcionar.Observe também que isso fornece os mesmos resultados que remover
s/________//g
e anexar&& sed -i 's/________//g' path_to_your_files/*.txt
ao final do comando, mas não requer a especificação do caminho duas vezes.Uma variação geral disso seria usar
\x0
ou_\x0_
substituir,________
se você souber que nenhum nulo aparece em seus arquivos, como sugerido por jthill .fonte
sed 's/ab/xy/' | sed 's/cd/ab/' .....
)sed
é um editor de stream. Ele procura e substitui avidamente. A única maneira de fazer o que você pediu é usar um padrão de substituição intermediário e alterá-lo no final.echo 'abcd' | sed -e 's/ab/xy/;s/cd/ab/;s/xy/cd/'
fonte
Isso pode funcionar para você (GNU sed):
Isso usa uma tabela de pesquisa que é preparada e mantida no espaço de espera (HS) e depois anexada a cada linha. Um marcador exclusivo (neste caso
\n
) é anexado ao início da linha e usado como um método para percorrer a pesquisa por todo o comprimento da linha. Quando o marcador chega ao final da linha, o processo termina e é impressa a tabela de pesquisa e os marcadores que estão sendo descartados.NB A tabela de pesquisa é preparada no início e um segundo marcador exclusivo (neste caso
:
) é escolhido para não colidir com as cadeias de substituição.Com alguns comentários:
A tabela funciona assim:
fonte
Pode ser uma abordagem mais simples para ocorrência de padrão único, você pode tentar como abaixo: echo 'abbc' | sed 's / ab / bc /; s / bc / ab / 2'
Minha saída:
Para várias ocorrências de padrão:
Exemplo
Espero que isto ajude !!
fonte
Tcl tem um builtin para este
Isso funciona movendo a string um caractere de cada vez, fazendo comparações de strings começando na posição atual.
Em perl:
fonte
Aqui está um
awk
baseado em oogassed
fonte