como emular “substituir a b b a” por um sed?

4

Eu estou tentando emular um comando replace que troca dois caracteres, com um script sed, mas a escolha óbvia:

sed -e 's/a/b/g' -e 's/b/a/g' 

não funciona. Você pode me mostrar como fazer isso corretamente?

    
por Mitten 10.11.2013 / 12:17

3 respostas

13

Eu usaria o comando translate tr por exemplo.

tr ab ba < input_file
    
por 10.11.2013 / 12:31
12

Se você quiser substituir apenas caracteres , não mais strings, use

sed -e 'y/ab/ba/'

ou o comando equivalente tr da resposta de X Tian. Para strings arbitrárias, você precisa trabalhar mais:

Se houver algum caractere que certamente não ocorra na entrada, como # (mesmo um caractere de controle fará), você pode usar algo como

sed -e 's/a/#/g;s/b/a/g;s/#/b/g;'

Como alternativa, você pode fazer alguns truques com prefixo:

sed -e '
s/a/xa/g;
s/b/xb/g;
s/xa/yb/g;
s/xb/ya/g;
s/ya/a/g;
s/yb/b/g;
'

ou seja: prefixo a cada a e b com x (que significa: ainda não modificado), substitua xa por yb e vice-versa (onde y significa: modificado) e remova todos os prefixos.

    
por 10.11.2013 / 12:29
2

Se você tem um personagem extra, você pode fazer a sugestão de Uwe.

Se você realmente só precisa substituir um único caractere e não precisa necessariamente de sed , use tr como sugerido por XTian.

Se você não precisa de sed e pode substituir sequências mais longas sem precisar de um caractere extra, você pode usar algo assim:

perl -le '%ex=(a=>"b",b=>"a"); $keys=join("|",keys(%ex)); $text="abba"; $text=~s/$keys/$ex{$&}/eg; print $text'

ou

ruby -e 'ex={"a"=>"b","b"=>"a"}; puts "abba".gsub(/(#{ex.keys.join("|")})/,ex)'
    
por 10.11.2013 / 12:42