¿Cómo traduce tr una palabra a otra?

9

Tengo un archivo ma.txty contiene la salida de ls -l; cuando ejecuto el trcomando ( tr "nik-pc" "root") obtengo esta salida:

nik-pc@nik:~$ cat ma.txt 
total 52
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 Desktop
lrwxrwxrwx 1 nik-pc nik-pc    2 Mar  8 22:54 di -> hd
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 13:28 Documents
drwxr-xr-x 7 nik-pc nik-pc 4096 Mar 14 18:21 Downloads
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 09:39 dwhelper
-rw-r--r-- 1 nik-pc nik-pc 2134 Mar 13 17:40 hd
-rw-r--r-- 1 nik-pc nik-pc    3 Mar 13 15:34 m
-rw-r--r-- 1 nik-pc nik-pc    0 Mar 17 19:48 ma.txt
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 14:58 Music
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 12:30 Pictures
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Public
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 13 15:58 sd
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Templates
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Videos
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 xdm-helper

nik-pc@nik:~$ tr "nik-pc" "root" < ma.txt 
tttat 52
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 Desottt
trwxrwxrwx 1 too-tt too-tt    2 Mar  8 22:54 do -> hd
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 13:28 Dttutetts
drwxr-xr-x 7 too-tt too-tt 4096 Mar 14 18:21 Dtwtttads
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 09:39 dwhetter
-rw-r--r-- 1 too-tt too-tt 2134 Mar 13 17:40 hd
-rw-r--r-- 1 too-tt too-tt    3 Mar 13 15:34 t
-rw-r--r-- 1 too-tt too-tt    0 Mar 17 19:48 ta.txt
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 14:58 Musot
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 12:30 Pottures
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Pubtot
drwxr-xr-x 2 too-tt too-tt 4096 Mar 13 15:58 sd
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Tetttates
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Vodets
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 xdt-hetter

En la línea uno reemplazó "nik" por "también" y la ortografía de "Escritorio" se convirtió en "Desottt".

¿Por qué es esto? ¿Qué es la lógica detrás de esto?

Manish Bharti
fuente
3
info coreutils 'tr invocation'te dice en detalle lo que trhace.
Nephente
44
¿Qué estás tratando de hacer por cierto? El mandato dio exactamente lo que dijo que hacer, pero supongo que realmente desea reemplazar nik-pccon root?
kos
3
El primer paso es siempre verificar la página del comando man.
Mostafa Ahangarha
1
@DavidZ: Tenga en cuenta que ntambién está en el k-prango. POSIX no especifica el resultado de un carácter que aparece más de una vez en el primer conjunto.
hmakholm dejó a Mónica el
1
Creo que lo que realmente necesitas es el sedcomando ... ls -l | sed 's/nik-pc/root/'haría lo que quieras. tres para convertir caracteres individuales, por ejemplo. minúscula a mayúscula, o cambio de línea de estilo dos (\ r) a estilo Unix (\ n), o algo así como reemplazar todas las barras diagonales inversas (Windows) con barras inclinadas. También puede eliminar caracteres "no deseados", por ejemplo. todos los números o todas las letras mayúsculas.
Baard Kopperud

Respuestas:

16

trtraduce una cadena de caracteres sabio. Busca las letras del primer conjunto y las reemplaza por las del segundo conjunto.

Tuviste nik-pccomo primer set. trexpande la k-pparte en que a todas las letras en el rango de "k" a "p", por lo que el conjunto es igual a niklmnopc.

Tu segundo set fue root.

Lo que trahora hace es buscar todas las apariciones del primer carácter en el primer conjunto (evaluado) y reemplazarlas con el primer carácter del segundo conjunto. Cuando no hay más caracteres en el conjunto 2, simplemente repite su último carácter. Ver la tabla a continuación:

n --> r
i --> o
k --> o
l --> t
m --> t
n --> t
o --> t
p --> t
c --> t

Así que ahora está claro por qué, por ejemplo, "Escritorio" se convierte en "Desottt". El comportamiento es completamente correcto y está destinado de esta manera.


En cambio, lo que estás buscando se puede lograr usando sed:

sed 's/nik-pc/root/g' ma.txt

La sintaxis es esta:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Así que dejamos que busque el patrón "nik-pc" y reemplace toda la coincidencia con "root". Necesitamos agregar la bandera "g" para habilitar el reemplazo global. Sin eso, solo reemplazaría cada primer partido por línea.

Byte Commander
fuente
Esa tabla con flechas hace que la explicación sea aún más clara, eso me gusta. + 1-ed. Un usuario probablemente podría hacer algo similar conprintf "A\nB\nC\n" | tr 'ABC' '12'
Sergiy Kolodyazhnyy
18

tres para traducir caracteres, no para palabras completas. Puede traducir conjuntos. En su ejemplo, tiene "nik-pc" como caracteres de la primera colección, y "root" es otro. De hecho, k-pes un rango, por lo que incluye todos los caracteres desde k hasta p. Coincidirá con los caracteres uno por uno, por lo que n se traducirá en r, i a o, k a o, y cualquier otra cosa más allá de 4th char será t. Es por eso que tienes "Escritorio" traducido a "Desottt"

Puedes verlo más claramente en este ejemplo:

$ echo "ABCDEF" | tr "ABCDEF"  "12"                            
122222

Aquí puede ver que el tr conjunto 1 tiene D en la posición 4. Pero el conjunto 2 no tiene la posición 4, por lo que utilizará la última posición que el conjunto 2 tiene que traducir.

Lo que estás haciendo es traducir una palabra a otra. Lo que quieres hacer es usar una herramienta más avanzada como sedo awk.

Por ejemplo,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd
Sergiy Kolodyazhnyy
fuente
66
O sed s / nik-pc / root / g ma.txt> ma2.txt
Bruni
1
Eras mucho más rápido que yo @Serg ...: P
Byte Commander
2
@ByteCommander Puede que haya ganado en velocidad, pero creo que su respuesta gana en calidad
Sergiy Kolodyazhnyy