El comando TR
Hoy presentaremos el comando tr, un comando muy infravalorado en esencia por dos motivos.
- Primero: Es un gran desconocido para el usuario estándar.
- Segundo: Muy a menudo se sustituye por las funciones de buscar y reemplazar de cualquier editor de texto.
Si sois capaces de terminar de leer este articulo, posiblemente no podréis evitar maldecir las horas que seguramente habréis perdido en el pasado editando interminables ficheros de texto.
Sintaxis
El comando tr dado un flujo de datos (entrada estándar) nos permite modificarlos sustituyendo y/o borrando carácteres.
Su sintaxis es un poco liosa, pero miraremos de explicarla lo mejor que podamos.
tr [OPCIÓN] ... SET1 [SET2]
Donde [OPCIÓN] pueden ser cualquiera de las siguientes.
- -d Borrar los carácteres indicados en SET1
- -s Elimina o reemplaza los carácteres repetidos indicados en SET1
- -c Todos los carácteres que no sean los indicados en SET1 los convierte en SET2
- -t Trunca SET1 a la longitud de SET2
Sustitución
Empezaremos con unos ejemplos sencillos que os ayudaran a entenderlo mejor. En su forma más simple, podemos sustituir un carácter por otro, por ejemplo, podemos transformar todas las vocales en mayúsculas.
$ echo murcielago | tr aeiou AEIOU mUrcIElAgO
En esta ocasión hemos ejecutado el comando tr sin ningún argumento, 'aeiou' seria SET1 y 'AEIOU' corresponderia a SET2.
Quisiera matizar que hablamos de caráteres, por lo tanto los patrones SET1 y SET2 son a nivel de carácteres, por lo que tr buscará cualquier aparición de SET1 en la cadena de entrada y la sustituirá por el carácter correspondiente de SET2.
La sustitución se realiza a pares, el primer carácter de SET1 será reemplazado por el primer carácter de SET2, el segundo con el segundo y así hasta el final.
Pero que ocurre si SET1 tiene mayor longitud que SET2? o al revés, veamoslo.
$ echo murcielago | tr aeiou AE mErcEElAgE $ echo murcielago | tr aeiou AE. m.rc.ElAg. $ echo murcielago | tr ae AEIOU murciElAgo
Creo que con esos ejemplos es fácil deducir lo que ha pasado, en el primer ejemplo, podemos ver como ha sustituido todas las 'a' y 'e' por 'A' y 'E' respectivamente, pero que ha pasado con el resto de vocales que había en SET1?.
Pues simplemente que al buscar su homólogo en SET2 y no encontrarlo, este es sustituido por el último caracter de este, en nuestro ejemplo por 'E'. Tal vez este efecto lo veréis mejor en el segundo ejemplo donde la 'a' y 'e' son sustituidas por su correspondiente mayúscula, y el resto de las vocales se sutituyen por el carácter '.'.
El tercer ejemplo es mas fácil de entender, simplemente busca los caracteres de SET1 en la cadena introducida, y cuando los encuentra los sustituye por sus homólogos en SET2, ignorando así los últimos carácteres de SET2.
Dicho de otra forma, si SET1 es mayor que SET2, este último se expandirá rellenándose con el último carácter de SET2 hasta conseguir la longitud de SET1.
Es importante que entendáis el concepto de carácter, estamos sustituyendo carácteres, si en SET1 tenemos 'en', el comando tr no buscará la palabra 'en', sino que buscará todas las apariciones de la letra 'e' y la letra 'n'.
Borrar
El borrado de carácteres es más fácil de usar. En este caso solo necesitamos SET1, para indicar que carácteres queremos borrar.
En el siguiente ejemplo borraremos las letras 'a' y 'e' de la palabra 'murcielago'.
$ echo murcielago | tr -d ae murcilgo
Si ya se, es una chorrada de ejemplo, tal vez este os parezca mejor. Eliminaremos todos los espacios en blanco que tengamos repetidos en una frase.
$ echo 'una frase muy tonta pero valdrá' | tr -d ' ' unafrasemuytontaperovaldrá
Borrar repetidos
Como veis, en el ejemplo anterior, hemos eliminado todos los espacios repetidos, pero también los que no lo estaban. El problema lo hemos tenido al elegir la opción -d, pues como hemos indicado al inicio, su función es eliminar. Para este trabajo en concreto tenemos la opción -s cuya especialidad es la de eliminar carácteres repetidos. Veámosla en acción.
~$ echo 'una frase muy tonta pero valdrá' | tr -s ' ' una frase muy tonta pero valdrá
A que ahora le empezáis a ver más sentido a esta herramienta, pues aún no hemos acabado, la opción -s nos permite eliminar los carácteres repetidos y a la vez sustituirlos por otro carácter.
$ echo 'una frase muy tonta pero valdrá' | tr -s ' ' .
una.frase.muy.tonta.pero.valdrá
$ echo '(((una frase muy tonta pero valdrá)))' | tr -s ' )(' ' ]['
[una frase muy tonta pero valdrá]
Sustituir con negados
Si utilizamos la opción -c, el comando localizará todos los carácteres que no coincidan con el patrón dado en SET1 y los reemplazara por sus correspondientes en SET2.
Es un poco más difícil ver la funcionalidad de esta opción, pero creedme la tiene, veamos unos ejemplos tontos para que entendáis su uso y más adelante veremos algo más útil.
$ echo 'naci el 13-12-1966' | tr -c '0123456789' '-' --------13-12-1966-
Si habéis ejecutado este último ejemplo, habréis visto que el resultado ha sido algo raro, que es lo que ha pasado?. Fijaros en el último guión del resultado.
El comando tr ha substituido por un guión cualquier carácter que no fuera un número. Pues eso ha hecho, el salto de línea aunque invisible también es tenido en cuenta como un carácter.
Secuencias válidas
El comando reconoce los siguientes carácteres no visibles.
\NNN carácter con valor octal NNN (de uno a tres dígitos) \\ barra invertida \a pitido audible (BEL) \b espacio hacia atrás \f salto de página \n salto de línea \r retorno de carro \t tabulación horizontal \v tabulación vertical
El comando ls sin argumentos, nos devuelve una lista tabulada por columnas con el nombre de los archivos de un directorio determinado, con tr podemos modificar la salida del comando ls para obtener una lista con un elemento por línea.
$ ls |tr '\t' '\n' gedit.banyut.1053685335 kde-banyutyHf1n2 keyring-GLhk1g ksocket-banyut orbit-banyut orbit-root plugtmp pulse-banyut screenlets seahorse-7f0yeD Tracker-banyut.8264 virtual-banyut.F7zFmY
Hemos substituido los tabuladores por saltos de linea, también podríamos cambiar las barras de un path.
$ echo '\banyut\tmp\' |tr '\\' '/' /banyut/tmp/
Rangos
SET1 y SET2 se pueden definir como un rango de carácteres, esto se consigue mediante el carácter '-', por ejemplo para definir los números del 0 al 9, se escribirá, 0-9.
Como ejemplo convertiremos todo un texto a mayúsculas.
$ echo 'Yo soy porque nosotros somos' | tr a-z A-Z YO SOY PORQUE NOSOTROS SOMOS
A demás, también tenemos predefinidos una serie de rangos.
[:alnum:] todas las letras y dígitos [:alpha:] todas las letras [:blank:] todos los espacios en blanco horizontales [:cntrl:] todos los caracteres de control [:digit:] todos los dígitos [:graph:] todos los caracteres imprimibles, sin incluir el espacio [:lower:] todas las letras minúsculas [:print:] todos los caracteres imprimibles, incluyendo el espacio [:punct:] todos los caracteres de puntuación [:space:] todos los espacios en blanco horizontales y verticales [:upper:] todas las letras mayúsculas [:xdigit:] todos los números hexadecimales [=CAR=] todos los caracteres que son igual que CAR
El ejemplo anterior utilizando los rangos predefinidos.
$ echo 'Yo soy porque nosotros somos' | tr [:lower:] [:upper:] YO SOY PORQUE NOSOTROS SOMOS
Bueno a estas alturas ya tenéis que tener las ideas claras de como funciona esta instrucción, por lo que solo nos queda poner unos cuantos ejemplos, más que nada, encaminados a mostrar las distintas formas de llamar al comando tr.
$ tr -d [:cntrl:] <fitx_A.txt >fitx_B.txt $ cat fitx_A.txt | tr 'a-zA-Z' 'A-Za-z' $ tr -c '[:print:]\n' <fitx_A.txt '.' $ ls | tr [:upper:] [:lower:] > fitx_C.txt
Si alguien tiene algún problema interpretando las anteriores lineas, pues que lo diga y miraremos de explicarlo un poco mejor.
- - -
Si su Windows no le da problemas. ¡Reclame a Microsoft!



Comentarios sobre El comando TR
Gracias por el artículo. Son muchos los comandos/herramienta que tienen los *nix. Para mi tr es todo un descubrimiento.
Saludos.