AWK: Pasar texto a minúsculas/mayúsculas

Publicado el Martes, 22 de julio de 2008

Lo bueno de aprender AWK es que al tenerlo fresco, se convierte en una herramienta de uso diario en el shell. Últimamente lo uso mucho, por ejemplo hoy, lo usé en el siguiente caso que les voy a plantear. Necesitaba pasar un texto a minúsculas, que era algo que no sabía cómo hacer, hasta que lo necesité. En verdad tenía un archivo de texto (items.txt) lleno de datos con el siguiente formato:

* TITULO DEL ITEM - Descripción del ítem.

Lo que necesitaba era obtener una lista así:
titulo del item 1, titulo del item 2, ... , titulo del item n.
Y obviamente, lo primero que se me ocurrió fue usar AWK.

<conceptosAWK>
AWK es un lenguaje de programación interpretado orientado a datos. Recibe texto como entrada, y trabaja con eso. Ejecuta una acción por cada línea de texto, y a su vez, cada dato "separado" en esa linea de texto es un registro al que se accede con $1, $2, ... , $n.
El separador de registros es importante. Por defecto toma el espacio como separador.
</conceptosAWK>

En este archivo en particular, opté empezar por separar el título de su descripción. Primero proceso el archivo para eliminar lo que hay después del guión. Para eso especifico que el separador de campo sea el guión "-":

awk 'BEGIN{FS="-"}{print $1}' items.txt > resultado.txt

Lo que estoy haciendo acá, es especificando que separe los registros por "-". Entonces $1 va a ser "* TITULO DEL ITEM" y $2 va a ser "Descripción del ítem.". Le paso como parámetro items.txt, y voy guardando el resultado en resultado.txt. (Redirijo la salida del awk con ">" a un archivo de texto resultado.txt).

El archivo resultado.txt me queda con el formato: "* TITULO DEL ITEM" para cada ítem. Ahora lo paso a minúsculas, y de paso saco el asterisco que no lo necesito:

awk 'BEGIN{FS="*"}{print tolower($2", ")}' $2

Me quedó algo así:
titulo del item 1 , titulo del item 2 , ... , titulo del item n ,
Ahora, lo que tengo que hacer sacar el espacio antes de las comas, para eso puedo usar SED:

sed s/\ ,/,/

Reemplazo los " ," con "," y listo. El archivo quedó:
titulo del item 1 , titulo del item 2 , ... , titulo del item n ,

Me hice un script, que recibe como parámetros dos archivos. El primer parámetro $1, es el archivo que hay que editar, y el segundo parámetro $2 va a ser el resultado:

#!/bin/bash

awk 'BEGIN{FS="-"}{print $1}' $1 > $2
echo `awk 'BEGIN{FS="*"}{print tolower($2", ")}' $2` > $2
echo `sed s/\ ,/,/ $2` > $2

Lo novedoso, por lo menos para mí, fue el uso de la función "tolower" en AWK. Así que para pasar un texto a minúsculas o a mayúsculas de forma bien sencilla, simplemente hay que usar esta función. Idem para pasar a mayúsculas: toupper. Los scripts quedarían algo así:

Para pasar todo el texto a minúsculas:

tolower.sh
#!/bin/bash

echo $@ | awk '{print tolower($0)}'
#Este script pasa a minúsculas todos los parámetros que reciba.

Para pasar todo el texto a mayúsculas:

toupper.sh
#!/bin/bash

echo $@ | awk '{print toupper($0)}'
#Este script pasa a mayúsculas todos los parámetros que reciba.

O directamente, si se acuerdan cómo usar AWK, lo más rápido es hacerlo derecho desde consola.

Y tá, eso es lo que estuve haciendo en un rato. Como estuvo divertido, lo documenté por acá 😛
En una de esas a alguien le sirve.

17 comentarios en este post

Feed de comentarios
  1. Avatar

    fernando 22 julio. 2008 - 22:34

    Rodolfo:
    Gracias por el aporte. En verdad había encontrado la forma de hacerlo con tr, así tal cual mencionas, pero me resultó más divertido AWK 😛
    Creo que no hay forma de poner los símbolos de mayor y menor, siempre tengo problema con eso:
    Usando code:"<"
    Usando pre:

    <

    Usando "<": <

  2. Avatar

    fernando 22 julio. 2008 - 22:35

    Bueno, con los tags “<pre>” anda, también escribiendo el equivalente al símbolo en HTML: & l t ; y & g t ;
    (Si los pongo juntos me escribe <>)

  3. Avatar

    Fabio R Panettieri 23 julio. 2008 - 12:20

    Ya se que es un post de AWK pero justo recien hice un scriptcito en python para hacer justo eso, y lo queria compartir

    Espero que no l otomen a mal, y que sirva para aportar

    #!/usr/bin/env python
    import sys
    try:
        input = open(sys.argv[1], r)
        str = input.read()
    except Exception, exp:
        print Error opening %s : %s % (sys.argv[1], exp)
    finally:
        input.close()

    if str:
        str = str.lower()
        try:
            output = open(sys.argv[2], w)
            output.write(str)
        except Exception, exp:
            print Error opening %s : %s % (sys.argv[2], exp)
        finally:
            output.close()

    • Avatar

      fitorec 11 enero. 2011 - 17:52

      Revisando tu script, lo unico que hace es convertir a minusculas no?, es decir:

      cat entrada.txt | tr[:upper:]‘ ‘[:lower:]> salida.txt

      yo creo que le faltare la parte donde donde eliminas todo lo que esta seguido del – y también los * al inicio, de echo ahora que lo pienso desde python lo ideal es atrapar con una expresion regular lo que esta dentro de * y del -,
      si importas re (import re) a tu código solo le faltaría remplazar el el procesamiento de convertir en minusculas por el de convertir y seleccionar lo deseado:

      cat entrada.txt | tr[:upper:]‘ ‘[:lower:]> salida.txt

  4. Avatar

    fitorec 11 enero. 2011 - 17:35

    Hola para ser honesto desconozco mucho de awk, parte de esto es por que creo que existen múltiples formas de hacer lo mismo aveces son distintos comandos, cuando me encuentro con este tipo de problemas personalmente empleo: sed, grep, tr (comandos viejos de Unix), para mi minería de datos, dejo las instrucciones de como hacer lo mismo con ellos:

    #Eliminando todo lo que esta después del guión menos.
    cat items.txt | sed -r  "s/(.*)-.*/1,/g"
     
    #Remplazar mayúsculas por minusculas
    cat items.txt | tr '[:upper:]' '[:lower:]'
     
    #Sustitución del asterisco seguido de un espacio(s):
     
    cat items.txt | sed -r  "s/*s//g"
     
     
    #!/bin/bash
    sed -r  "s/*s//g;s/(.*)-.*/1,/g" $1 > $2
    cat $1 | tr '[:upper:]' '[:lower:]' > $2

    Es sólo otra forma de hacerlo, realmente el awk a mi parecer suele ocupar un poco más de recursos(lo puedes comprobar con un time).

    Sin mas interesantes tus posts, me dare una vuelta mas seguido por estos andares ;¬D,

    • Avatar

      fitorec 11 enero. 2011 - 18:03

      para de conversiones, lo que queda perfecto es el tr, dejo unos ejemplos útiles:

      # Convertir de Minúsculas a Mayúsculas
      echo Minúsculas-Mayúsculas | tr '[:lower:]' '[:upper:]'
      # Convertir de Mayúsculas a Minúsculas
      echo Mayúsculas-Minúsculas | tr '[:upper:]' '[:lower:]'
       
      #filtrado de caracteres.
      echo "3241j4lkio12j4k23n51kj52" | tr -dc 1234
       
      #Generando cadena aleatoria de 32 caracteres.
      hash=`<;/dev/urandom tr -dc [a-zA-Z0-9] | head -c 32`
      echo $hash

      En general el tr tiene muchos usos, date una vuelta por el manual.

    • Avatar

      Fernando 11 enero. 2011 - 22:26

      fitorec gracias por aportar tu forma de hacerlo. Es interesante postear este tipo de scripts por este mismo intercambio.

      Cuando me enfrento a alguna tarea de este tipo, generalmente pienso la manera de resolverla con AWK ya que fue algo que me quedó bastante fijado en el shell.

      De todas formas, lo mejor es ver las distintas formas en las que cada uno enfrenta el problema.

      Me tomé el atrevimiento de formatear un poco tus comentarios para que quedara resaltado el código, ya que aportan mucho.

      Tendré que leer el man de tr. Tengo un libro pendiente sobre Shell Scripting que cubre más de bash, sed y awk. Es un tema bastante interesante, así que seguiré con eso con el tiempo.

      Nuevamente gracias, y me alegro que te haya interesado el blog y te hayas tomado el tiempo de dejar tan buenos comentarios. Bienvenido, nos leeremos por acá.

      Saludos!

  1. Cómo mostrar código fuente en los comentarios | Picando Código | 23 julio. 2008 - 13:42

    […] recientes fernando on AWK: Pasar texto a minúsculas/mayúsculasJulián Franco on El regreso de Los FarzantesFabio R Panettieri on AWK: Pasar texto a […]

  2. Renombrar varios archivos desde la línea de comando | Picando Código | 12 enero. 2011 - 08:21

    […] AWK: Pasar texto a minúsculas/mayúsculas […]

Dejar un comentario

Toasty!