Subsecciones


Comandos para el procesamiento de textos

Además de los ya vistos (vi, grep, sed) existen una serie de comandos para manejar ficheros de texto, como tac, rev, nl, head, tail, sort, uniq, expand, fmt, cut, paste, tr, join, split, wc, od o awk

Comandos simples

Existe una serie de comandos simples para realizar operaciones concretas sobre ficheros de texto

Comentaremos brevemente cada uno de ellos

sort

ordena alfabéticamente líneas de texto y las muestra en la salida estándar

Formato:

sort [opciones] fichero

Algunas opciones:

Ejemplos:

$ cat nombres.txt
María Pérez
luis Andión
Adriana Gómez
jorge pena

$ sort nombres.txt
Adriana Gómez
María Pérez
jorge pena
luis Andión
$ sort -f nombres.txt
Adriana Gómez
jorge pena
luis Andión
María Pérez

$ sort -f +1 +0 nombres.txt #Obsoleto (no usar)
luis Andión
Adriana Gómez
jorge pena
María Pérez

$ sort -f -k 2,2 nombres.txt
luis Andión
Adriana Gómez
jorge pena
María Pérez

cut

Escribe partes seleccionadas de un fichero a la salida estándar; puede usarse para seleccionar columnas o campos de un fichero específico

Formato:

cut [opciones] fichero

Algunas opciones:

Ejemplos:

$ cat nombres-ord.txt
Luis Andión
Adriana Gómez
Jorge Pena
María Pérez
$ cut -c 1-7 nombres-ord.txt
Luis An
Adriana
Jorge P
María P

$ cut -c 1-5,9-10 nombres-ord.txt
Luis ió
AdriaGó
Jorgena
Maríare

$ cut -d ' ' -f 1 nombres-ord.txt
Luis
Adriana
Jorge
María

paste

Permite unir texto de varios ficheros, uniendo las líneas de cada uno de los ficheros

Formato:

paste [opciones] fichero1 [fichero2] ...

Algunas opciones:

Ejemplos:

$ cat nombres.txt
Luis
Adriana
Jorge
María

$ cat apellidos.txt
Andión
Gómez
Pena
Pérez

$ paste nombres.txt apellidos.txt
Luis Andión
Adriana Gómez
Jorge Pena
María Pérez

$ paste -d ' ' nombres.txt apellidos.txt
Luis Andión
Adriana Gómez
Jorge Pena
María Pérez

$ paste -s -d '\t\n' nombres.txt
Luis Adriana
Jorge María

fmt

Formatea cada párrafo, uniendo o separando líneas para que todas tengan el mismo tamaño

Algunas opciones:

Ejemplo:

$ cat quijote.txt
En un lugar de la Mancha, de cuyo nombre no
quiero acordarme, no ha mucho tiempo
que vivía un
hidalgo de los de lanza en astillero, adarga
antigua, rocín flaco y galgo corredor.

$ fmt -w 45 -u quijote.txt
En un lugar de la Mancha, de cuyo nombre
no quiero acordarme, no ha mucho tiempo
que vivía un hidalgo de los de lanza en
astillero, adarga antigua, rocín flaco y
galgo corredor.

tr

Borra caracteres o reemplaza unos por otros

Formato:

tr [opciones] set1 set2

Algunas opciones:

Ejemplos:

$ tr 'a-z' 'A-Z' < quijote.txt
EN UN LUGAR DE LA MANCHA, DE CUYO NOMBRE...
$ tr -d ' ' < quijote.txt
EnunlugardelaMancha,decuyonombre...
$ tr au pk < quijote.txt
En kn lkgpr de lp Mpnchp, de ckyo nombre...
$ tr lcu o < quijote.txt | tr -s o
En on ogar de oa Manoha, de oyo nombre

uniq

Descarta todas (menos una) las líneas idénticas sucesivas en el fichero

Formato:

uniq [opciones] fichero

Algunas opciones:

Ejemplo:

$ cat nombres.txt
Julio Lorenzo
Pedro Andión
Celia Fernández
Celia Fernández
Juan Fernández
Enrique Pena

$ uniq nombres.txt
Julio Lorenzo
Pedro Andión
Celia Fernández
Juan Fernández
Enrique Pena

$ uniq -f 1 -c nombres.txt
    1 Julio Lorenzo
    1 Pedro Andión
    3 Celia Fernández
    1 Enrique Pena

join

Permite combinar dos ficheros usando campos: busca en los ficheros por entradas comunes en el campo y une las líneas; los ficheros deben estar ordenados por el campo de unión

Formato:

join [opciones] fichero1 fichero2

Algunas opciones:

Ejemplo:

$ cat nombres1.txt
Luis Andión
Adriana Gómez
Jorge Pena
María Pérez

$ cat nombres2.txt
Pedro Andión
Celia Fernández
Julio Lorenzo
Enrique Pena

$ join -j 2 nombres1.txt nombres2.txt
Andión Luis Pedro
Pena Jorge Enrique

$ join -j 2 -o 1.1 2.1 0 nombres1.txt nombres2.txt
Luis Pedro Andión
Jorge Enrique Pena

split

Divide un fichero en ficheros más pequeños; los ficheros más pequeños se nombran a partir del prefijo especificado (prefijoaa, prefijoab,...)

Formato:

split [opciones] fichero prefijo

Si no se pone fichero, o se pone - se lee la entrada estándar

Algunas opciones:

Ejemplo:

$ split -l 2 quijote.txt quij
$ ls quij*
quijaa quijab quijac quijote.txt
$ cat quijaa
En un lugar de la Mancha, de cuyo nombre
no quiero acordarme, no ha mucho tiempo

$ cat quijac
galgo corredor.
$ split -l 2 -d quijote.txt quij
$ ls quij*
quij00 quij01 quij02 ...

head

Muestra el principio de un fichero

Formato:

head [opciones] fichero

Algunas opciones:

Ejemplo:

$ head -n 2 -v quijote.txt
==>quijote.txt <==
En un lugar de la Mancha, de cuyo nombre
no quiero acordarme, no ha mucho tiempo

tail

Muestra el final de un fichero

Algunas opciones:

Ejemplo:

$ tail -n 2 -v quijote.txt
==>quijote.txt <==
astillero, adarga antigua, rocín flaco y
galgo corredor.

tac, rev

tac imprime el fichero de la última a la primera línea (opuesto a cat); rev invierte las lineas del fichero

Ejemplos:

$ tac quijote.txt
galgo corredor.
astillero, adarga antigua, rocín flaco y
que vivía un hidalgo de los de lanza en
no quiero acordarme, no ha mucho tiempo
En un lugar de la Mancha, de cuyo nombre

$ rev quijote.txt
erbmon oyuc ed ,ahcnaM al ed ragul nu nE
opmeit ohcum ah on ,emradroca oreiuq on
ne aznal ed sol ed ogladih nu aíviv euq
y ocalf nícor ,augitna agrada ,orellitsa
.roderroc oglag

wc

Muestra el número de líneas, palabras y bytes de un fichero

Formato:

wc [opciones] fichero

Algunas opciones:

Ejemplo:

$ wc quijote.txt
5 33 178 quijote.txt
$ wc -l quijote.txt
5 quijote.txt
$ wc -w quijote.txt
33 quijote.txt
$ wc -c quijote.txt
178 quijote.txt

nl

Añade números de línea; nl considera los ficheros separados en páginas lógicas, cada una de ellas con una cabecera, cuerpo y pie, cada una de estas secciones se numera de forma independiente, y la numeración se reinicia para cada página; los comienzos de cabecera, cuerpo y pie de cada página se marcan, respectivamente, con \:\:\:, \:\: y \:

Formato:

nl [opciones] fichero

Algunas opciones:

Ejemplo:

$ nl -s 'q ' quijote.txt
    1q En un lugar de la Mancha, de cuyo nombre
    2q no quiero acordarme, no ha mucho tiempo
    3q que vivía un hidalgo de los de lanza en
    4q astillero, adarga antigua, rocín flaco y
    5q galgo corredor.

expand

Convierte TABs en espacios; útil debido a que la representación del TAB puede ser diferente en distintos sistemas

Formato:

expand [opciones] fichero ...

Algunas opciones:

Ejemplos:

$ cat hola.c
main() {
                for(i=0; i<10;i++)
                                printf("Hola mundo!\n");
}
$ expand -t 2 hola.c
main() {
for(i=0; i<10;i++)
printf("Hola mundo!\n");
}

El comando unexpand hace la operación contraria

od

Muestra un fichero en octal, hexadecimal o otros formatos; en cada línea muestra (en la primera columna) el offset

Formato:

od [opciones] fichero

Algunas opciones:

Ejemplo:

$ od -t x -A x quijote.txt
000000 75206e45 756c206e 20726167 6c206564
000010 614d2061 6168636e 6564202c 79756320
000020 6f6e206f 6572626d 206f6e0a 65697571
...

awk

Lenguaje diseñado para procesar datos basados en texto; el nombre AWK deriva de los apellidos de los autores: Alfred V. Aho, Peter J. Weinberger, y Brian W. Kernighan

Funcionamiento básico

awk lee el fichero que se le pase como entrada (o la entrada estándar) línea a línea, y sobre cada línea ejecuta una serie de operaciones

Ejemplo:

# echo -e interpreta "\n" como un retorno de carro,
# lo que envía 2 líneas al comando awk
$ echo -e "\n" | awk '{ print "Hola mundo!" }'
Hola mundo!
Hola mundo!

Formas de ejecutar awk

Podemos usar awk de varias formas:

Ejemplos:

$ echo '{ print "Hola mundo!" }' > hola.awk
$ echo -e "\n" | awk -f hola.awk
Hola mundo!
Hola mundo!
$ echo '#!/usr/bin/awk -f' > hola.awk
$ echo '{ print "Hola mundo!" }' » hola.awk
$ chmod +x hola.awk
$ echo -e "\n" | ./hola.awk
Hola mundo!
Hola mundo!

Estructura de un programa awk

Un programa awk tiene tres secciones:

  1. Parte inicial, que se ejecuta sólo una vez, antes de empezar a procesar la entrada:
    BEGIN { operaciones }
  2. Parte central, con instrucciones que se ejecutan para cada una de las líneas de la entrada; tienen en siguiente formato:
    /PATRÓN/ { operaciones }
    las operaciones se realizan sólo sobre las líneas que verifiquen la REGEXP indicada en PATRÓN
  3. Parte final, se efectúa sólo una vez, después de procesar la entrada:
    END { operaciones }

Manejo de ficheros de texto

awk divide las líneas de la entrada en campos:

Ejemplos:

$ ls -ldh * |\
> awk '{print "Fichero ", $8, "ocupa ", $5, "bytes"}'
Fichero proba ocupa 36 bytes
Fichero uy_hist1_nodos.txt ocupa 9,1K bytes
Fichero vimbook-OPL.pdf ocupa 3,7M bytes

$ df -h | sort -rnk 5,5 |\
> awk 'BEGIN { print "Nivel de ocupación" }\
> /^\/dev\/hd/ {print "Partición ",$6,": ",$5}\
> END { print "Terminado" }'
Nivel de ocupación
Partición /home : 87% ocupación
Partición /mnt/hda2 : 51% ocupación
Partición / : 38% ocupación
Terminado
$ # Usando un fichero
$ cat ocupacion.awk
BEGIN {
         print "Nivel de ocupación"
}
/^\/dev\/hd/ {
         print "Partición ",$6,": ", $5
}
END { print "Terminado" }
$ df -h | sort -rnk 5,5 | awk -f ocupacion.awk

Variables predefinidas: awk tiene un conjunto de variables predefinidas, como FS que nos permite especificar el separador de campos

Esas variables son:

Nombre Significado
FS Carácter separador entre campos de entrada (por defecto, blanco o tabulado)
NR Número de registros de entrada
NF Número de campos en el registro de entrada
RS Carácter separador entre registros de entrada (por defecto, nueva línea)
OFS Carácter separador entre campos en la salida (por defecto, un espacio en blanco)
ORS Carácter separador entre registros de salida (por defecto, nueva línea)
FILENAME Nombre del fichero abierto

Ejemplo:

$ cat usuarios.awk
BEGIN {
     FS = ":"; OFS = " -->"; ORS = "\n============\n";
}
{
     print NR, $1, $5
}
$ awk -f usuarios.awk /etc/passwd
...
37 -->tomas -->Tomás Fernández Pena„,
============
38 -->caba -->José Carlos Cabaleiro Domínguez„,
============
...

Otras características

awk es un lenguaje completo:

La sintaxis de awk es prácticamente idéntica a la del lenguaje C

Ejemplos:

  1. Lista el tamaño de los ficheros y el tamaño total
    $ cat lista-ficheros.awk
    BEGIN { total = 0; }
    {
         total += $5;
         printf("Fichero %s ocupa %d bytes\n", $8,$5);
    }
    END {
         printf("Ocupación total = %d bytes\n", total);
    }
    $ ls -ld * | awk -f lista-ficheros.awk
    Fichero ancestros.awk ocupa 370 bytes
    Fichero hola.c ocupa 66 bytes
    Fichero lista-ficheros.awk ocupa 143 bytes
    Ocupación total = 579 bytes
  2. Muestra una advertencia si el nivel de ocupación de una partición supera un límite
    $ cat ocupacion2.awk
    BEGIN { limite = 85; }
    /^\/dev\/hd/ {
         if($5 > limite)
             printf("PELIGRO: el nivel de ocupación de %s es %s\n%", $6, $5);
    }
    $ df -ah | tr -d '%' | awk -f ocupacion2.awk
    PELIGRO: el nivel de ocupación de /home es 87%

Paso de parámetros: es posible pasar parámetros en la llamada a awk
Ejemplo: Indicando el PID de un proceso obtiene el PID de todos sus ancestros (padres, abuelos, ...)

$ cat ancestros.awk
BEGIN { ind=0; }
function padre(p) {
     for(i=0; i <ind; i++)
         if(pid[i] == p) return(ppid[i]);
}
!/PID/ { pid[ind]=$3; ppid[ind]=$4; ind++; }
END {
     do {
         printf("%d --> ", proc); proc = padre(proc);
     } while(proc >= 1);
     printf("\n\n");
}
$ ps axl | awk -f ancestros.awk proc=4258
4258 --> 3326 --> 1 -->

Arrays asociativos: awk permite el uso de arrays asociativos, es decir, que pueden tener como índice una cadena de caracteres

Ejemplo

$ cat usuarios2.awk
BEGIN { FS = ":" }
{ nombre[$1] = $5; }
END {
    for(;;){
        printf("Nombre de usuario: ");
        getline user < "-";
        if( user == "" )
            break;
        printf("<%s>: %s\n", user, nombre[user]);
    }
}
$ awk -f usuarios2.awk /etc/passwd
Nombre de usuario: tomas
<tomas>: Tomás Fernández Pena„,
Nombre de usuario:

Funciones predefinidas

En awk existen una serie de funciones predefinidas

Administración de Sistemas e Redes <ASR.USC[at]gmail.com>
Tomás Fernández Pena <tf.pena[at]usc.es>
Última actualización: 30-09-15 17:44 por tomas

Creative Commons License
Curso de Administración de Sistemas y Redes por Tomás Fernández Pena se distribuye bajo la licencia Creative Commons Recoñecemento-Compartir baixo a mesma licenza. 3.0 España.
Trabajo original en persoal.citius.usc.es/tf.pena/ASR.