¿Cómo funcionan las opciones '-s', '-t' y '-c' del comando tr en Unix?

11

Estoy confundido con respecto a la forma -s, -ty -copciones de trabajo en el tr comando. Cuando lo hago

echo I am a good boy | tr good bad

Me sale la salida:

I am a bddd bdy

Esto es bastante comprensible, ya que ose repite en good. El último cambio posible en lugar de oes d, y por lo tanto, la salida.

Ahora cuando lo hago

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

la salida es

I am a bd bdy

Se -ssupone que la opción exprime cada ocurrencia repetida de cada carácter en el conjunto 1 en una sola ocurrencia y luego cambia cada carácter en el conjunto 1 en el carácter correspondiente en el conjunto 2 que está en la misma posición.

Entonces debería haber sido

I am a bad bay.

¿Por qué el cambio?

Además, cuando lo hago

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

yo obtengo dddddddgoodddodd

¿Cómo funciona la -copción tr, refiriéndose a este ejemplo?

Y finalmente: cómo cambiarme de un buen chico a un chico malo .... :): P Eso es,

echo I am a good boy | tr <something>me da la salida como: I am a bad boy.

dig_123
fuente

Respuestas:

11

-s Interruptor: apretar (eliminar caracteres repetidos)

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

salida: i am a bd bdy

Hay dos cosas que suceden detrás de escena que hacen que esto suceda. En primer lugar, si el segundo argumento para tres más corto que el primero, entonces se repite el último carácter en el segundo argumento para que tenga la misma longitud que el primero. Entonces el comando equivalente es:

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

La otra cosa que está sucediendo es que cuando los caracteres en el primer argumento se repiten, sobrescriben cualquier ocurrencia previa (me refiero a los dos oos en good). Esto hace que el comando ahora sea equivalente a:

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

(el segundo oal dreemplazo sobrescribe el anterior oal areemplazo, haciéndolo redundante)

Sin el -sinterruptor, la salida sería

i am a bddd bdy

Con el -sinterruptor tr'aprieta' los caracteres repetidos que se enumeran en el último argumento que sale de la salida final:

i am a bd bdy

-c Switch: Complemento

El -cinterruptor se usa para hacer coincidir el complemento del primer argumento (es decir, todos los caracteres que no figuran en el argumento 1). Como resultado, arg 1 contendrá muchas letras (256-3). Ahora, lo mismo le sucede a arg 2 que en el caso anterior: el carácter final de Arg 2 se repite para que coincida con la longitud o Arg 1. Entonces, la declaración original:

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

es equivalente a:

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

(tenga en cuenta lo que falta g, oy den el primer conjunto, también tenga en cuenta que dreemplazará a todos los demás caracteres en el segundo conjunto, incluido el carácter de espacio)

Por eso se i am a good boyconvierte endddddddgoodddodd

Más información aquí: http://www.linuxjournal.com/article/2563

ltn100
fuente
Generalmente correcto, excepto que el -scambio hace trque exprima cualquier carácter del último argumento a tr(no el primero, como usted dice) que se repite en la entrada. Esto se observa en el artículo que vinculó y se explica en el último párrafo en la sección "Descripción" de la página del manual .
ravron
4

Su comprensión de -ses incorrecta, reemplaza las apariciones repetidas de caracteres en el conjunto 1 en la entrada con un solo carácter. no modifica el conjunto, p. ej.

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

da

i am a bad bay

La -copción reemplaza el conjunto 1 con su complemento (es decir, el conjunto de todos los caracteres no contenidos en el conjunto 1). Puede usar esto para eliminar todos los caracteres excepto los especificados, por ejemplo.

echo i am a good boy | tr -cd gobdy

salidas

goodboy
Hasturkun
fuente
: Entendí tu punto con respecto a la opción -s, pero mi pregunta es cómo: echo, soy un buen chico | tr -s bueno malo está dando salida como: soy un bd bdy esto solo es posible cuando esto sucede: primero soy un buen chico se cambia a soy un bddd bdy luego la opción -s cambia las ocurrencias de múltiples d's a solo es decir: soy un bddd bdy luego cambia a soy un bd bdy ¿es esto lo que realmente está sucediendo? por favor, desglosen esto para mí, lo mismo con la opción -c, ¿cómo es echo? Soy un buen chico | tr -cd gobdy dando esto: goodboy
1

Las otras respuestas cubiertos tr's -s, -ty -copciones, pero está completo:

Tiene problemas porque eligió la herramienta incorrecta.

  • tr es para transformaciones de personajes
  • sed es para la edición de transmisiones.

Dado que ambos goody badson secuencia de caracteres en la secuencia sedes una mejor coincidencia.

echo I am a good boy | <something> me da la salida como: I am a bad boy

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

El s/..../..../es sustituto. Lo que coincida con la primera expresión regular se reemplazará con la segunda. La /gbandera al final es para reemplazo global de esta manera, todas las ocurrencias serán reemplazadas, no solo la primera.

$ 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.
Aaron Goldman
fuente
0

si. ¡exactamente!

tr -s reemplaza instancias de caracteres repetidos con un solo carácter.

(a través de la página de manual)

entonces, va así:

se convierte gooda bddd. Las instancias repetidas son 3 'd's.

entonces reemplaza estas tres instancias con una sola instancia.

eso es lo hace bd. :)

Rahul Mishra
fuente
2
No esperamos que todas las respuestas sean perfectas, pero las respuestas con ortografía, puntuación y gramática correctas son más fáciles de leer.
Ashildr