Como as opções '-s', '-t' e '-c' do comando tr funcionam no Unix?

10

Estou confuso em relação à maneira como as opções -s , -t e -c funcionam no tr comando. Quando eu faço

echo I am a good boy | tr good bad

Eu recebo a saída:

I am a bddd bdy

Isso é bastante compreensível, pois o é repetido em good . A última mudança possível no lugar de o é d e, portanto, a saída.

Agora, quando faço

echo I am a good boy | tr -s good bad

a saída é

I am a bd bdy

A opção -s deve pressionar cada ocorrência repetida de cada caractere no conjunto 1 em uma única ocorrência e, em seguida, alterar cada caractere no conjunto 1 para o caractere correspondente no conjunto 2, que está na mesma posição.

Então deveria ter sido

I am a bad bay.

Por que a mudança?

Além disso, quando eu faço

echo I am a good boy | tr -c good bad

Eu recebo dddddddgoodddodd

Como a opção -c funciona para tr , referindo-se a este exemplo?

E finalmente: como mudar de um bom menino para um bad boy .... :): P Isto é,

echo I am a good boy | tr <something> me dá a saída como: I am a bad boy .

    
por dig_123 09.11.2011 / 14:30

4 respostas

9

-s Switch: Squeeze (remova caracteres repetidos)

echo i am a good boy | tr -s good bad

output: i am a bd bdy

Há duas coisas acontecendo nos bastidores que fazem isso acontecer. Em primeiro lugar, se o segundo argumento para tr for menor que o primeiro, então o último caractere no segundo argumento será repetido para torná-lo o mesmo comprimento que o primeiro. Então o comando equivalente é:

echo i am a good boy | tr -s good badd

A outra coisa que está acontecendo é quando os caracteres do primeiro argumento são repetidos sobrescrevem qualquer ocorrência anterior (estou me referindo aos dois oo s em good ). Isso faz com que o comando agora seja equivalente a:

echo i am a good boy | tr -s god bdd

(a segunda substituição o to d substitui a substituição o a a anterior, tornando-a redundante)

Sem a opção -s , a saída seria

i am a bddd bdy

Com o -s switch tr 'aperta' qualquer caractere repetido listado no primeiro argumento, deixando a saída final:

i am a bd bdy

-c Switch: complemento

A opção -c é usada para corresponder ao complemento do primeiro argumento (ou seja, todos os caracteres não listados em arg 1). Como resultado, arg 1 conterá muitas letras (256-3). Agora, a mesma coisa acontece com arg 2 como no caso anterior: o caractere final de Arg 2 é repetido para corresponder ao tamanho ou Arg 1. Portanto, a declaração original:

echo i am a good boy | tr -c good bad

é equivalente a:

echo i am a good boy | tr abcefhijklmnp... baddddddddddd...

(observe os g , o e d ausentes no primeiro conjunto, observe também que d substituirá todos os outros caracteres no segundo conjunto - incluindo o caractere de espaço)

É por isso que i am a good boy se transforma em dddddddgoodddodd

Mais informações aqui: link

    
por 09.11.2011 / 16:58
4

Seu entendimento de -s está incorreto, ele substitui ocorrências repetidas de caracteres no conjunto 1 na entrada com um único caractere. não modifica o conjunto, por exemplo.

echo i am a good boy | tr -s god bad

i am a bad bay

A opção -c substitui o conjunto 1 pelo seu complemento (ou seja, o conjunto de todos os caracteres não contidos no conjunto 1). Você pode usar isso para remover todos, exceto os caracteres especificados, por exemplo.

echo i am a good boy | tr -cd gobdy

saídas

goodboy
    
por 09.11.2011 / 14:46
1

As outras respostas cobriram as opções tr -s , -t e -c mas para completar:

Você está com problemas porque pegou a ferramenta errada.

  • tr é para transformações de caracteres
  • sed é para edição de fluxo.

Como os campos good e bad são a sequência de caracteres no fluxo, sed é uma correspondência melhor.

echo I am a good boy | <something> me dá a saída como: I am a bad boy

$ echo I am a good boy | sed s/good/bad/g
I am a bad boy

O s/..../..../ é substituto. O que coincidir com a primeira expressão regular será substituído pelo segundo. A bandeira /g no final é para substituição global, desta forma todas as ocorrências serão substituídas não apenas pela primeira.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/
I am a bad boy and a good boy is me.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/g
I am a bad boy and a bad boy is me.
    
por 21.02.2018 / 18:46
0

sim. exatamente!

tr -s substitui instâncias de caracteres repetidos por um único caractere.

(via página man.)

então, é assim:

converte good para bddd . instâncias repetidas são 3 'd's.

então substitui essas três instâncias por uma única instância.

é isso que faz bd. :)

    
por 11.10.2013 / 13:23

Tags