LPIC

Guía extraoficial de estudio

Archivos en la Categoría: 2: Procesamiento de flujos de texto usando filtros

Comando sed

Sed

Este comando modifica directamente el contenido del fichero, enviándolo a la salida estándar.

Su sintaxis puede adoptar dos formas:

sed [opciones] -f fichero-script [fichero-entrada]
sed [opciones] texto-script [fichero-entrada]

Fichero-entrada será en nombre del fichero que se desea modificar. Texto-script o fichero-script, son el conjunto de comandos que queremos que ejecute sed.

Veamos algunos de los comandos de sed que puede emplear en sus scripts. El campo direcciones, hace referencia a los números de linea. Pueden no recibir direcciones, en cuyo caso se opera con el fichero completo. Si se recibe una dirección, se opera sobre la linea especificada. Si se reciben dos direcciones ( un rango ), se opera sobre dicho rango de lineas, ambas inclusive.

Comando Direcciones significado
= 0 o 1 Muestra el número de linea actual.
a\ texto 0 o 1
Añade el texto al fichero.

i\texto
0 o 1 Inserta el texto en el fichero.
r fichero 0 o 1 añade el texto del fichero indicado en el fichero.
c\texto rango Reemplaza el rango de lineas seleccionado con el texto proporcionado.
s/regexp/sustituto rango Reemplaza el texto que coincida con la expresión regular por el sustituto.
w fichero rango Escribe el espacio de patrones actual en el fichero especificado.
q 0 o 1 Finaliza de inmediato el script, pero imprime el espacio de patrones actual.
Q 0 o 1 Finaliza de inmediato el script.

Un ejemplo para dicho comando podría ser el siguiente:

sed ‘s/2008/2009/’ cal-2008.txt > cal-2009.txt

la idea de este ejemplo es convertir rápidamente un fichero creado para el 2008 para que se pueda utilizar en el 2009.

Sed reemplazará la primera aparición de 2008 de cada linea por 2009 y lo canaliza al fichero cal-2009.txt.

Comandos para resumir ficheros (cut y wc)

En esta entrada vamos a ver los los últimos comandos de filtrado de texto que nos faltan. Veamos los comandos cut y wc.

Cut

Es utilizado para la extracción de segmentos (campos, caracteres o bytes) de un fichero de entrada para mostrarlos por la salida estándar. Sus opciones son:

Flag Resultado
-b o –bytes Corta por el número de bytes especificados
-c o –characters Corta por el número de caracteres especificados
-f o –fields Corta por el número de campos especificados. Por defecto los campos están delimitados por una tabulación, aunque podemos cambiar el carácter delimitador con “-d carácter_delimitador”).

Con ejemplos lo entenderemos mejor. Vamos a ver el formato del fichero passwd:

[super@localhost ~]$ cat /etc/passwdsuper:x:1000:1000:super:/home/super:/bin/bash
usuario1:x:1002:1000:usuario1:/home/usuario1:/bin/bash
usuario2:x:1003:1000:usuario2:/home/usuario2:/bin/bash
usuario3:x:1004:1000:usuario3:/home/usuario3:/bin/bash
usuario4:x:1005:1000:usuario4:/home/usuario4:/bin/bash

En este caso, los campos están delimitados por “:”, y no por tabulaciones. Tendremos que usar el flag -d para cambiar el campo delimitador. Si quisiéramos obtener un listado de los usuarios del sistema y su directorio home (campos 1 y 6), deberíamos ejecutar la siguiente orden:

[super@localhost ~]$ cat passwd | cut -f1,6 -d”:”
super:/home/super
usuario1:/home/usuario1
usuario2:/home/usuario2
usuario3:/home/usuario3
usuario4:/home/usuario4

Observamos que hemos utilizado -f1,6 para que nos corte los campos 1 y 6. Si quisiéramos que nos cortara todos los campos que van del 1 al 6, la sintaxis sería -f1-6, y si en vez de campos, queremos cortar por caracteres, seria -c1-6, para cortar los caracteres del 1 al 6.

Wc (Word Count)

Comando que genera un contador de palabras, lineas o bytes. Su uso es muy sencillo y útil.

[super@localhost ~]$ wc /etc/passwd
36   56 1788 /etc/passwd

El resultado nos indica que el fichero contiene 36 lineas, 56 palabras y 1788 bytes. Si queremos especificar un único formato de salida, se haría con

Flag Resultado
-l o –lines Cuenta las lineas
-w o –words Cuenta las palabras
-c o –bytes Cuenta los bytes
-m o –chars Cuenta los caracteres

Comandos para transformar ficheros: expand, sort, split, uniq y tr

Los comandos que vamos a comentar no cambian realmente el contenido de los ficheros, sino que envían el fichero modificado a la salida estándar. Después, podemos canalizar la salida a otro comando o fichero.

expand : convertir tabulaciones en espacios:

Interesante comando para los que programan pequeños scripts o programas desde un editor de texto. Todavía recuerdo la primera vez que lo utilicé. Estuve varios días programando un programa en python, era para una práctica que tenia que presentar. Después de que el profesor modificara las lineas de código que creyera oportunas, el programa devolvía errores de indexación todos lados. Motivo? pues el editor de texto que yo utilicé tenia definidos las tabulaciones como tabulaciones (lógico), y mi profesor tenia la opción marcada de gedit de “insertar espacios en lugar de tabulaciones” y ancho de tabulador 4. Cada vez que pulsaba el tabulador, insertaba cuatro espacios. Fue tan sencillo como hacer:

[super@super Documentos]$ expand -t 4 prog.py > prog_con_espacios.py
El comando unexpand, hace lo opuesto, convierte varios espacios en tabulaciones. También acepta la opción -t num.

sort: ordenar ficheros

Sort (en inglés ordenar), es utilizado para ordenar la salida de un comando. Tenemos el documento abecedario.txt que contiene letras al azar. Para mostrar una salida ordenada:

[super@super Documentos]$ sort abecedario.txt
c
d
d
e
f
g
h
q
r
s
t
x
x
z
Recordemos que sort ordena por el valor ASCII, el cual distingue entre letras mayúsculas y minúsculas.

Algunas de las opciones de este comando son:

Flag Resultado
-f o –ignore-case Ignora entre mayúsculas y minúsculas
-M o –month-sort Ordena por las abreviaturas de tres letras de los meses (de JAN a DEC)
-r o –reverse Invierte el orden
-n o –numeric-sort Ordenación numérica
-k campo o –fey=campo Permite definir el campo de la ordenación

split: dividir ficheros

Este comando nos permite dividir un fichero en dos o más.

Algunas de las opciones de este comando son:

Flag Resultado
-b tamaño o –bytes=tamaño Divide el fichero por bytes. Puede corta un fichero por la mitad de una linea.
-C tamaño o –line-bytes=tamaño Divide un fichero por el numero de bytes especificado sin romper sus lineas.
-l lineas o –lines=lineas Divide un fichero en bloques no superiores al número de lineas especificado.

El siguiente comando nos genera los ficheros aba, abe, abc, etc, con tres lineas cada uno, extraidas del fichero abecedario.txt:

split -l 3 abecedario.txt ab

uniq: eliminación de lineas duplicadas

Nos permite eliminar todas las lineas que sean idénticas.

Supongamos que al ordenar un fichero, queda de la siguiente manera:

[super@super Documentos]$ sort fichero.txt
aa
aa
bb
bb
cc
cc

Para eliminar duplicados ejecutamos:

[super@super Documentos]$ sort fichero.txt | uniq
aa
bb
cc

tr : traducción de carácteres

Su sintaxis puede resultar un poco confusa para algunos:

tr [OPCIÓN] … SET1 [SET2]

Veamos algunos ejemplos para entenderla mejor. Queremos convertir todas las vocales de la siguiente frase a mayúsculas:

[super@super Documentos]$ echo frase de ejemplo | tr aeiou AEIOU
frAsE dE EjEmplO

También podemos utilizar dicho comando para eliminar ciertos caracteres, con -d:

$ echo hola | tr -d o
hla

Ahora eliminiaremos todos los espacios repetidos que tengamos en una frase con la opción -s:

[super@super Documentos]$ echo ‘esto es       una frase    con    espacios  repetidos’ | tr -s ‘ ‘
 esto es una frase con espacios repetidos

Comandos para combinar ficheros: cat, join y paste

Combinar ficheros con cat

Aunque este comando es utilizado para mostrar el contenido de ficheros pequeños, lo cierto es que és una herramienta para combinar ficheros (cat es abreviatura de concatenar). Utilizando este comando con una redirección de salida, se puede combinar dos ficheros en uno:

cat fichero_1.txt fichero2.txt > fichero_combinado.txt

Algunas de las opciones que ofrece son:

Flag Resultado
-E o –show-ends Muestra el signo dolar al final de cada linia ($)
-n o –number Numera las lineas al comienzo de cada una
-b o –number-nonblank Solo numera las lineas que contienen texto
-s o –squeeze-blank Substituye los grupos de lineas en blanco por una sola
-T o –show-tabs Muestra los carácteres de tabulación como ^I
El comando tac (cat al revés), invierte el orden de las lineas al mostrarlas

Asociar de ficheros por campos con join

Este comando combina dos ficheros según el campo que hayamos especificado. Por defecto join tiene en cuenta el primer campo para realizar la combinación.

Si fichero1.txt contiene:

08020 sant marti
03030 sant andreu

y el fichero2.txt:

telefono 999933993
telefono 223232323

Vemos que sucede al ejecutar el comando join:

[super@super Documents]$ join fichero1.txt fichero2.txt
08020 sant marti telefono 999933993
03030 sant andreu telefono 223232323

En el siguiente caso, mezclamos tomando como referencia los campos número dos de ambos ficheros:

join -1 2 -2 2 fichero1.txt fichero2.txt

-1 y -2 hacen referencia al fichero según el orden por el que es introducido en el comando. En este caso “-1” es fichero1.txt porque lo escribimos antes, y “-2” fichero2.txt.  El dígito que ponemos después de este sirve para indicar por que campo de este fichero queremos asociar, en este caso hemos escogido el campo dos de los dos ficheros.

Es importante que los ficheros estén ordenados por el campo que se van a mezclar.

Fusionar líneas con paste

La función de este fichero es la de fusionar ficheros línea a línea, separando las líneas de cada fichero mediante tabulaciones.

Teniendo en cuenta que el contenido de fichero1.txt y fichero2.txt es el mismo que en el ejemplo anterior, el resultado de este comando:

[super@super Documents]$ paste fichero1.txt fichero2.txt

sería:

08020 sant marti    telefono 999933993
03030 sant andreu    telefono 223232323
Para que el resultado tenga sentido, los ficheros deben tener el mismo número líneas.

Flujos estándares y su redirección

De entre los diferentes tipos de flujo, definiremos los tres que destacan:

  • Entrada estándar (stdin): Es la utilizada para recoger información. En la mayoría de los casos es a través del teclado.
  • Salida estándar (stdout): Se usa para enviar información al exterior. Suele ser el monitor.
  • Error estándar (stderr) : Es utilizada para llevar los mensajes  de error y de alta prioridad.

Ahora veamos una tabla con los operadores comunes de redirección:

Operador Efecto
> Crea un fichero que contiene la salida estándar. Si el fichero existe, se sobrescribe.
>> Añade al fichero la salida estándar. Si el fichero no existe, se sobrescribe.
2> Crea un fichero con la salida de error estándar. Si el fichero no  existe, se crea.
2>> Añade a un fichero la salida de error estándar. Si el fichero no existe, se crea.
&> Crea un fichero que contiene tanto el error estándar como la salida estándar. Si el fichero existe, se reemplaza.
<> El fichero especificado se  utiliza tanto para la salida estándar como para la entrada estándar.
< El contenido del fichero especificado se envía para utilizarlo como entrada estándar
<< Acepta el texto de las siguientes lineas como entrada estándar.

Veamos ejemplos:

  • Operador “>”:
super@linux-jweh:~> echo envio frase a fichero  >  fichero.txt
super@linux-jweh:~> cat fichero.txt
envio frase a fichero
  • Operador “>>”:

En este ejemplo, vemos como el resultado de ejecutar la orden “ls Descargas” se añade a fichero.txt:

super@linux-jweh:~> ls Descargas >> fichero.txt
super@linux-jweh:~> cat fichero.txt
envio frase a fichero
299859_10150486380139606_800839605_11184435_1607766419_n.jpg
bbgf126.wmv
gbbm12.jpg
gbbm25.jpg
gbbm26.jpg
install-apt4suse.rpm
libapt-pkg-libc6_9-6-2-0.5.15lorg3.2-123.12.i586.rpm
Public
Public.zip
  • Operador “2>”:

Ahora vamos a intentar listar una carpeta que no existe, y enviar los errores a un fichero:

super@linux-jweh:~> ls carpeta_no_existe >> fichero.txt 2>errores.txt
super@linux-jweh:~> cat errores.txt
ls: no se puede acceder a carpeta_no_existe: No existe el fichero o el directorio

Como vemos, no muestra ningún error por pantalla diciendo que la carpeta no existe, ya que hemos redirigido la salida de error al fichero “errores.txt”

  • Operador “2>>”:

Este comando haría exactamente lo mismo que el anterior, solo que las lineas de error se añadirían a las ya existentes.

  • Operador “&>”:

Podríamos decir que este operador actúa como “>” y “2>” a la vez. Vamos a listar una carpeta que existe y otra que no, redirigiendo su salida a fichero.txt.

super@linux-jweh:~> ls carpeta_no_existe Descargas/ &> fichero.txt
super@linux-jweh:~> cat fichero.txt
ls: no se puede acceder a carpeta_no_existe: No existe el fichero o el directorio
Descargas/:
299859_10150486380139606_800839605_11184435_1607766419_n.jpg
bbgf126.wmv
gbbm12.jpg
gbbm25.jpg
gbbm26.jpg
install-apt4suse.rpm
libapt-pkg-libc6_9-6-2-0.5.15lorg3.2-123.12.i586.rpm
Public
Public.zip

Vemos que tanto los errores como el resultado de “ls Descargas” se guardan en el mismo fichero.

  • Operador “<>”:

Utilizamos fichero.txt para tanto para la salida estándar como para la entrada estándar.

super@linux-jweh:~> <> fichero.txt
  • Operador “<“:

En el siguiente ejemplo vemos como cambiamos a al vez la entrada y salida estándar de un programa. Cogemos el contenido de “fichero.txt” y lo enviamos a “fichero2.txt”.

super@linux-jweh:~> cat < fichero.txt > fichero2.txt

Podríamos haber omitido el uso de “<” y en este caso el resultado hubiera sido el mismo. Unix dispone de un gran número de comandos que leen de la entrada estándar, realizan la operación con el texto y escriben en la salida estándar: cat, grep, soft, cut, sed, tr…

  • Operador “<<“:

Hacemos que “programa” acepte la entrada hasta que vea una linea que contiene solo EOF:

 super@linux-jweh:~> programa << EOF
> hola
> EOF