miércoles, 20 de junio de 2012

Comandos útiles


Comando de Linux, con expresiones regulares


Comando grep

El comando grep nos permite buscar, dentro de los archivos, las líneas que concuerdan con un patrón. Bueno, si no especificamos ningún nombre de archivo, tomará la entrada estándar, con lo que podemos encadenarlo con otros filtros.

Por defecto, grep imprime las líneas encontradas en la salida estándar. Es decir, que podemos verlo directamente la pantalla, o redireccionar la salida estándar a un archivo.
Como tiene muchísimas opciones, vamos a ver tan sólo las más usadas:

-c En lugar de imprimir las líneas que coinciden, muestra el número de líneas que coinciden.

-e PATRON nos permite especificar varios patrones de búsqueda o proteger aquellos patrones de búsqueda que comienzan con el signo -.

-r busca recursivamente dentro de todos los subdirectorios del directorio actual.

-v nos muestra las líneas que no coinciden con el patrón buscado.

-i ignora la distinción entre mayúsculas y minúsculas.

-n Numera las líneas en la salida.

-E nos permite usar expresiones regulares. Equivalente a usar egrep.

-o le indica a grep que nos muestre sólo la parte de la línea que coincide con el patrón.

-f ARCHIVO extrae los patrones del archivo que especifiquemos. Los patrones del archivo deben ir uno por línea.

-H nos imprime el nombre del archivo con cada coincidencia.

Algunos ejemplos:

- Buscar todas las palabras que comiencen por a en un archivo:
$ grep “a*” archivo

Otra forma de buscar, sería:
$ cat archivo | grep “a*”

- Mostrar por pantalla, las líneas que contienen comentarios en el archivo /boot/grub/menu.lst:
$ grep “#” /boot/grub/menu.lst

- Enviar a un fichero las líneas del archivo /boot/grub/menu.lst que no son comentarios:
$ grep -v “#” /boot/grub/menu.lst

- Contar el número de interfaces de red que tenemos definidos en el fichero /etc/network/interfaces:
$ grep -c “iface” /etc/network/interfaces

- Mostrar las líneas de un fichero que contienen la palabra BADAJOZ o HUELVA:
$ grep -e “BADAJOZ” -e “HUELVA” archivo

- Mostrar las líneas de un fichero que contienen la palabra BADAJOZ o HUELVA, numerando las líneas de salida:
$ grep -n -e “BADAJOZ” -e “HUELVA” archivo

- Mostrar los ficheros que contienen la palabra TOLEDO en el directorio actual y todos sus subdirectorios:
$ grep -r “TOLEDO” *

Veamos algunos ejemplos con expresiones regulares:
- Obtener la dirección MAC de la interfaz de red eth0 de nuestra máquina:
$ ifconfig eth0 | grep -oiE ‘([0-9A-F]{2}:){5}[0-9A-F]{2}’

Sacamos la dirección MAC de la interfaz eth0 de nuestra máquina haciendo un:
ifconfig eth0

Y aplicando el filtro grep:

grep -oiE ‘([0-9A-F]{2}:){5}[0-9A-F]{2}’
Las opciones que he usado en grep son:

-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.

-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.

-E Indica que vamos a usar una expresión regular extendida.

En cuanto a la expresión regular, podemos dividirla en dos partes:

([0-9A-F]{2}:){5} Buscamos 5 conjuntos de 2 carateres seguidos de dos puntos

[0-9A-F]{2} seguido por un conjunto de dos caracteres.

Como las direcciones MAC se representan en hexadecimal, los caracteres que buscamos son los números del 0 al 9 y las letras desde la A a la F.

- Extraer la lista de direcciones de correo electrónico de un archivo:
grep -Eio ‘[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}’ fichero.txt

Utilizo las mismas opciones que en el caso anterior:

-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
-E Indica que vamos a usar una expresión regular extendida.
Analicemos ahora la expresión regular:
[a-z0-9._-]+@[a-z0-9.-]+[a-z]{2,4}
Al igual que antes, la vamos dividiendo en partes:
[a-z0-9._-]+ Una combinación de letras, números, y/o los símbolos . _ y – de uno o más caracteres
@ seguido de una arroba
[a-z0-9.-]+ seguido de una cadena de letras, números y/o los símbolos . y -
[a-z]{2,4} seguido de una cadena de entre dos y cuatro caracteres.
- Obtener la dirección IP de la interfaz de red eth1 de nuestra máquina:
$ ifconfig eth1 | grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’ | grep -v 255
En el ejemplo anterior, hemos tomado la información que nos ofrece ifconfig:
ifconfig eth1
Hemos filtrado dicha información con el comando grep, obteniendo todas las direcciones IP que aparecen:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’
Por último, hemos filtrado la salida del comando anterior, para eliminar la dirección de broadcast junto con la máscara de red para quedarnos sólo con la dirección IP de la máquina:
grep -v 255
La línea anterior no mostraría las líneas que no contengan el valor 255, es decir, las direcciones de broadcast y máscara de red.
Analicemos ahora el comando grep:
grep -oiE ‘([0-9]{1,3}\.){3}[0-9]{1,3}’
Al igual que en los otros dos ejemplos de expresiones regulares uso las opciones -oiE en el comando grep:
-o Indica que la salida del comando debe contener sólo el texto que coincide con el patrón, en lugar de toda la línea, como es lo habitual.
-i Lo he usado para que ignore la distinción entre mayúsculas y minúsculas.
-E Indica que vamos a usar una expresión regular extendida.
En cuanto a la expresión regular:
‘([0-9]{1,3}\.){3}[0-9]{1,3}’
([0-9]{1,3}\.){3}: Representa 3 bloques de entre uno y tres dígitos separados por puntos. Observemos que como el punto es un metacaracter, tengo que usar el caracter de escape \ para que no sea interpretado como un metacaracter, sino como un carácter normal.
[0-9]{1,3}: Representa el último bloque de la dirección IP, que está formado por un número de entre 1 y 3 dígitos.
El shell de linux: Manipulación de cadenas
En bash podemos realizar operaciones de manipulación de cadenas, como por ejemplo:
* Obtener la longitud de una cadena.
* Buscar caracteres dentro de una cadena.
* Extraer una subcadena de una cadena.
Obtener la longitud de una cadena de caracteres.-
Podemos obtener la longitud de una cadena de tres formas:
* ${#cadena}
* expr length $cadena
* expr “$cadena” : ‘.*’
Ejemplos:
$ micadena=”Bienvenido al mundo de Linux”
$ echo “La longitud de la cadena es: `expr length $micadena`”
$ echo “La longitud de la cadena obtenida de otro modo: `${#micadena}`”
Buscar una cadena dentro de otra cadena de caracteres.-
Podemos averiguar cual es la posición de una cadena dentro de otra, utilizando las siguiente expresión:
expr index cadena_donde_buscar cadena_a_buscar
Devuelve la posición donde encuentra los caracteres a buscar dentro de la cadena, si no, devuelve un 0.
Ejemplo:
micadena=”Bienvenido al mundo de Linux”
cadenaabuscar=”Linux”
echo “La cadena $buscar se encuentra en la pos `expr index $micadena $cadenaabuscar`”
Como podemos ver, index busca una cadena, pero si lo que queremos utilizar como patrón de búsqueda es una expresión regular, usaremos:
expr match cadena_donde_buscar patrón_caracteres_buscar
Ejemplo:
cadena=”342 ovejas en el redil”
numero=`expr match $cadena [0-9]*`
echo “El número de dígitos al comienzo de la cadena $cadena es: $numero”
Extraer una subcadena de una cadena de caracteres.-
Si queremos extraer una subcadena de una cadena de caracteres, utilizamos la siguiente expresión:
expr substr cadena posición n_caracteres
Para extraer una subcadena de una cadena indicamos la cadena, la posición y longitud a extraer.
Ejemplo:
$nif=”70245678D”
echo “El DNI de $nif es `expr substr $nif 1 8`”
echo “La letra del $nif es `expr substr $nif 9 1`”
Comando let
El comando let nos permite trabajar fácilmente con variables numéricas en scripts.
Por ejemplo: Supongamos que queremos multiplicar por 2 el valor de una variable y almacenar el resultado en otra:
$ simple=4
$ let doble=simple*2
Si después de ejecutar estas dos instrucciones en un terminal, hacemos un:
$ echo $doble
Veremos que la variable doble vale 8.
Un ejemplo completo: Hacer un bucle while que incremente el valor de una variable CONTADOR y vaya mostrando los valores que toma dicha variable:
#!/bin/bash
CONTADOR=0
MAX=20
while [ $CONTADOR -lt $MAX ]; do
let CONTADOR=CONTADOR+1
echo El contador es $CONTADOR
done

Comando find
Utilizamos este comando para buscar archivos dentro de una jerarquía de directorios. Pero, lo mejor de todo es que no sólo podemos buscar, sino que, además, podemos ejecutar acciones sobre los elementos localizados por el comando find.
Por otro lado, podemos realizar la búsqueda mediante varios criterios.
La sintaxis de este comando es:
find [ruta...] [expresión]
Veamos un ejemplo sencillo: Queremos buscar los archivos de imágenes con extensión .jpg en el directorio del usuario ambrosio:
$ find /home/ambrosio -name “*.jpg”
Otro ejemplo: Imaginemos que quiero listar los directorios que hay en el directorio actual:
$ find ./ -maxdepth 1 -type d
Ahora imaginemos que quiero listar los ficheros que se han modificado hoy en el directorio actual:
$ find ./ -mtime 0 -type f
Si quisieramos borrar todos los subdirectorios del directorio /var/backup que tengan una antigüedad mayor de 20 días:
$ find /var/backup -mtime +20 -type d -exec rm -f {} \;
Otro ejemplo: Queremos borrar todos los directorios del sistema que contengan la palabra sane:
# find / -name “*sane*” -type d -exec rm -fr {} \; 2>/dev/null
Si lo que queremos es borrar todos los ficheros del sistema que contengan la palabra sane, no tenemos más que cambiar el tipo en el comando anterior:
# find / -name “*sane*” -type d -exec rm -fr {} \; 2>/dev/null
Otro ejemplo: Imaginemos que queremos recopilar todos los ficheros mp3 que tenemos repartidos en diferentes directorios y moverlos a un único directorio:
# find / -name “*.mp3″ -exec mv {} /compartido/musica/ \;
Expresiones regulares
Una expresión regular es un patrón que nos permite buscar un texto formado por metacaracteres y caracteres ordinarios.
Los metacaracteres son ciertos caracteres con un significado específico dentro de una expresión regular. Estos caracteres tienen un significado que va más allá del símbolo que representan y tienen un comportamiento especial en una expresión regular.
Aquí tenéis una lista de metacaracteres que usamos en expresiones regulares:
* . Significa cualquier caracter.
* ^Indica el principio de una línea.
* $ Indica el final de una línea.
* * Indica cero o más repeticiones del caracter anterior.
* + Indica una o más repeticiones del caracter anterior.
* \< Indica el comienzo de una palabra.
* \> Indica el final de una palabra.
* \ Caracter de escape. Da significado literal a un metacaracter.
* [ ] Uno cualquiera de los caracteres entre los corchetes. Ej: [A-Z] (desde A hasta Z).
* [^ ] Cualquier caracter distinto de los que figuran entre corchetes: Ej: [^A-Z].
* { } Nos permiten indicar el número de repeticiones del patrón anterior que deben darse.
* | Nos permite indicar caracteres alternativos: Ej: (^|[?&])
* ( ) Nos permiten agrupar patrones. Ej: ([0-9A-F]+:)+
Ojo. En las expresiones regulares se distingue entre mayúsculas y minúsculas.
Si queremos representar un caracter entre la a y la z, lo haremos de la siguiente manera: [a-z]
Dentro del conjunto, podemos especificar todos los caracteres que queramos. Por ejemplo: [a-zA-Z] representaría los caracteres alfabéticos en minúsculas y mayúsculas. Eso sí. El conjunto representa a un sólo caracter.
Si lo que queremos es representar identificar un número o una letra, podríamos hacerlo así:
[a-zA-Z0-9]
Los conjuntos pueden representarse, nombrando todos y cada uno de los elementos, o el intervalo. Ej: [0-9] representa lo mismo que [0123456789].
Si queremos representar un número que se compone de cero o más dígitos: [0-9]*
Y si queremos representar un número que se compone de uno o más dígitos: [0-9]+
Si ahora queremos representar cualquier caracter menos los dígitos: [^0-9]
Ahora, imaginemos que queremos representar un número de 5 dígitos: [0-9]{5}
Y si quisieramos representar una palabra que tiene entre dos y cuatro caracteres: [a-zA-Z]{2,4}
Dentro de los conjuntos de caracteres individuales, se reconocen las siguientes categorías:

[:alnum:] alfanuméricos
[:alpha:] alfabéticos
[:cntrl:] de control
[:digit:] dígitos
[:graph:] gráficos
[:lower:] minúsculas
[:print:] imprimibles
[:punct:] de puntuación
[:space:] espacios
[:upper:] mayúsculas
[:xdigit:] dígitos hexadecimales

Vamos a ver algunos ejemplos de expresiones regulares:
# grep ‘^La’ fichero
El comando anterior nos devuelve todas las líneas del fichero que comienzan por La.
# grep ‘^ *La’ fichero
El comando anterior nos devuelve todas las líneas del fichero que comienzan por cualquier número de espacios seguido de La.
# grep ‘^\..*’ fichero
El comando anterior nos devuelve todas las líneas del fichero que comienzan por punto y tienen cualquier número de caracteres.
# ls -la | grep ‘ \..*’
El comando anterior nos devuelve la lista de ficheros que comienzan por un espacio seguido de un punto y cualquier número de caracteres, es decir, la lista de ficheros ocultos.
# ls -l | grep ‘^d’
El comando anterior nos devuelve la lista de ficheros que comienzan por d, es decir, la lista de directorios.
Awk
Awk busca ciertos patrones en la entrada, y la procesa de la manera especificada. Awk tiene una gran funcionalidad, pero esta mayor funcionalidad tiene su coste reflejado en una mayor complejidad del lenguaje.
awk dispone de un lenguaje completo, sintácticamente similar a C que tiene una gran potencia a la hora de reconocer patrones en la entrada, ya que permite especificar combinaciones de expresiones regulares.
Además, no es necesario procesar la entrada línea a línea. Awk permite escoger el carácter que indica el fin de un registro y procesar la entrada de registro en registro (En el lenguaje awk, un ‘registro’ es el equivalente a una ‘línea’).
Awk separa automáticamente cada registro en campos que pueden utilizarse individualmente.
Por defecto, un registro es una línea del fichero, lo que significa que el separador de registros es ‘\n’.
Por defecto, un campo es todo aquello que esté separado por espacios en blanco, es decir, una palabra. El separador de campos por defecto es ‘[ \t]‘ (espacio y tabulador).
Una posible sintaxis de awk sería:
awk [fichero_entrada]
Un programa de awk es una secuencia de sentencias patrón-acción, con un formato determinado, en el que las acciones se ejecutarán si en el registro actual se cumple el patrón.
El formato es el siguiente:
patrón {accion}
Suele ser necesario encerrar los programas de awk entre comillas, para evitar que el shell las interprete como caracteres especiales.
Hay que tener en cuenta dos cosas:
* Si no hay patrón, las acciones se ejecutan en todos los registros.
* Si no hay acciones, lo que se hace es ejecutar la acción por defecto, que es copiar el registro en la salida estándar.
Veamos un par de ejemplos o tres de uso de awk:
* Mostramos el nombre de usuario de todos los usuarios logueados en la máquina:
who|awk ‘{print $1}’
* Borramos todas las líneas vacías de un fichero:
awk ‘!/^$/ {}’ fichero
* Mostramos el nombre de usuario y el intérprete que usa:
awk ‘BEGIN {FS=”:”}; {print $1,$NF | “sort”}’ /etc/passwd
* Mostramos el nombre completo del usuario y su login:
awk ‘BEGIN {FS=”:”}; {print $1,$5 | “sort”}’ /etc/passwd
Variables
Como ya hemos dicho, awk dispone de un lenguaje completo, y, como cualquier otro lenguaje, dispone de variables. Las variables pueden ser de dos tipos:
* Variables predefinidas.
* Variables definidas por el usuario.
Veamos cuales son las variables predefinidas:
* FS (Field separator): Permite indicar a awk cuál es el caracter que separa los campos. Por defecto es el espacio. La forma de indicar a awk el caracter de separación de campos es la siguiente: FS = “caracter”. Por ejemplo: FS = “,”. Si hacemos FS = “”, estamos indicando a awk que cada carácter es un campo.
* NF (Number of fields): Contiene el número total de campos que contiene el registro que se está leyendo en cada momento.
* RS (Record separator): Contiene el carácter que indica a awk en qué punto del archivo acaba un registro y empieza el siguiente. Por defecto es el caracter “\n”.
* NR (Number of record): Contiene el número de orden del registro que se está procesando en cada momento.
* OFS (Output FS): La instrucción print inserta en la salida un carácter de separación cada vez que aparece una coma en el código. Mediante OFS, podemos indicar a awk que separe los campos mediante el separador que le indiquemos. Por ejemplo: OFS = “;”
En cuanto a las variables definidas por el usuario, se crean directamente al hacer referencia a ellas en expresiones.
Las variables pueden ser:
* Escalares: Almacenan un solo valor.
* Vectoriales: Como vectores o arrays. En awk, se pueden crear arrays asociativos, dado que el lenguaje nos permite usar una cadena como índice del array. Para referirnos a un elemento dentro de un array, lo haremos: nombre[ subíndice ].
Campos de entrada
En Awk se considera cada registro del archivo de entrada como una sucesión de campos delimitados por un carácter dado. Este carácter es, por defecto, el espacio.
En cualquier caso, podemos indicar a awk que considere otro carácter como separador de campos mediante la opción FS, tal y como podemos ver en ejemplos anteriores.
Cada uno de estos campos se numera de forma correlativa, según su posición en la línea (o registro), de la siguiente manera: $1, $2, $3, … Además, también podemos referirnos a la línea entera con $0.
Por otra parte, se puede forzar a procesar una línea carácter a carácter, dejando la variable “separador de campos” FS sin contenido. Si hacemos ésto, en $1 se tendrá el primer carácter de la línea, en $2 el segundo, etc.
El otro día me encontré con el siguiente ejercicio:
Hacer un script que visualice la lista de usuarios que se encuentran conectados en el sistema, mediante el siguiente formato: nº orden — nombre usuario, totalizando el nº de usuarios. Ejemplo:
1 — root
2 — df01
3 — df02
Utilizando awk, la solución es tan sencilla como la siguiente:
#/bin/bash
who -u|awk ‘BEGIN { i=0 } { i+=1; print i,”-”,$1 } END { print “Total usuarios ” i }’
Estructura básica de un programa con awk
Para entender fácilmente la estructura de un programa con awk, podemos fijarnos en el ejemplo anterior, en el que tenemos tres bloques:
* BEGIN { i=0 }
* { i+=1; print i,”-”,$1 }
* END { print “Total usuarios ” i }
El primero, se ejecuta al inicio. En este caso, hemos utilizado el bloque BEGIN para inicializar la variable i con valor 0.
El segundo bloque se ejecuta para cada patrón (o registro, como queramos llamarlo). En este caso, incrementa el valor de i, y lo muestra por pantalla seguido de un guión y el campo nº 1 (que en este ejemplo es el login del usuario) Como no hemos indicado ningún separador de campo, se toma por defecto el espacio.
El tercer bloque se ejecuta al final. ¿Y qué hace el bloque en el ejemplo? Imprimir el número total de usuarios.
Awk puede servirnos muy bien para procesar ficheros de texto, extraídos de bases de datos, en los que tenemos registros con campos de datos.
Como ya hemos dicho, awk dispone de un lenguaje completo, con sentencias, condicionales, bucles, estructuras … Una sentencia que puede sernos de utilidad en el procesamiento de ficheros, es el if. Veamos un ejemplo usando esta sentencia:
awk ‘{ if (x % 2 == 0) print “x is even”; else print “x is odd” }’
Comando diff
El comando diff nos permite comparar dos ficheros linea a linea y nos informa de las diferencias entre ambos ficheros. Diff tiene muchas opciones. Las que más uso son -w, -q, -y.
La sintaxis del comando es la siguiente:
diff [opciones] [fichero1] [fichero2]
Si queremos comparar dos ficheros, ignorando los espacios en blanco, utilizaremos el parámetro -w:
diff -w fichero1 fichero2
Si lo que queremos es que no nos muestre las diferencias, sino que tan sólo nos informe de si son diferentes o no:
diff -q fichero1 fichero2
Si queremos que nos muestre la salida con las diferencias marcadas a dos columnas:
diff -y fichero1 fichero2
Como en muchos otros comandos, también podemos utilizar la opción -i, que ignora la diferencia entre mayúsculas y minúsculas.

Comando date
date es otro de los comandos que utilizamos en ocasiones en scripts, como por ejemplo, cuando creamos un script que debe hacer copia de seguridad diaria. El nombre de las carpetas donde se almacena la copia de cada día se crea usando el comando date.
date presenta la fecha y la hora del sistema, datos que sólo puede modicar el usuario root y tiene que seguir el siguiente formato: MM DD HH MM [AA][ss]
Si utilizamos el comando date a secas, se nos mostrará la fecha y hora de la siguiente manera: día de la semana, mes, día, hora, zona horaria, año. Por ejemplo:
lun mar 3 12:51:22 CET 2008
Pero, normalmente en los scripts sólo utilizo el año, mes y día.
Para ver la fecha mediante otro formato, podemos hacerlo utilizando la siguiente sintaxis del comando:
date +formato
Opciones de formato de hora:
* H : presenta la hora en el formato de 00 a 23.
* k : presenta la hora de 0 a 23.
* M : presenta los minutos de 00 a 59.
* p : añadir AM o PM.
* l : presenta la hora de 1 a 12.
* r : presenta horas minutos segundos [A/P]o[A/M].
* T : presenta horas minutos segundos.
* a : presenta el día de la semana abreviado.
* A : presenta el día de la semana completo.
* b : presenta el mes abreviado.
* B : presenta el mes completo.
Opciones de formato de fecha:
* D : presenta meses días años.
* d : presenta día.
* m : presenta mes.
* y : presenta año con el formato 01.
* Y : presenta año con el formato 2001.
* j : nos presenta el número de día juliano.
Ejemplo práctico:
nombrefichero=`date +”backup%Y%m%d”`
De este modo, estoy creando un nombre de fichero que tendrá la siguiente forma, por ejemplo: backup20080303

Comando sed
Este comando también lo usamos mucho, porque nos permite, de una forma cómoda, borrar líneas, registros o sustituir cadenas de caracteres dentro de las líneas.
* Para borrar una línea hacemos lo siguiente:
sed ‘nº_de_línead’ fichero
* Podemos indicar un número de línea concreto. Por ejemplo:
sed ’1d’ fichero
* Podemos indicar un intervalo de líneas a borrar. Por ejemplo:
sed ’3,5d’ fichero
* También podemos indicar que queremos borrar desde una determinada línea en adelante:
sed ’3,$d’ fichero
* Otro ejemplo útil es borrar las líneas en blanco de un fichero:
sed ‘/^$/d’ fichero
A la hora de borrar, también podemos especificar una cadena, de tal forma que el comando borrará todas las líneas que contengan esa cadena. Ejemplo:
cat fichero | sed ‘/^[ ]*$/d’ > ficherodestino
Lo anterior borrará todas las líneas en blanco de fichero.
Otro de los usos más interesantes de sed es sustituir cadenas. Podemos sustituir una cadena por otra de la siguiente manera:
sed ‘s/cadena1/cadena2/’ fichero
Al ejecutar el comando anterior, se sustituye la primera cadena que encuentra por la segunda. Pero, si lo que queremos es sustituir todas las cadenas que encuentre, en cada una de las líneas, añadimos el parámetro g :
sed ‘s/cadena1/cadena2/g’ fichero
Por otra parte, también podemos hacer que sustituya la cadena1 por la cadena2 en un número de línea concreto:
sed ’5 s/USUARIO/usuario/g’ fichero
Con cadenas de texto normales la cosa es sencilla, pero al que más y al que menos le resulta complicado cuando lo que hay que sustituir son caracteres especiales como el tabulador: \t o el caracter de nueva línea: \n. Pero veamos como tampoco es complicado: Imaginemos que tenemos un fichero con campos en los que el separador es el tabulador y queremos sustuir este caracter separador por otro caracter separador, como por ejemplo el punto y coma (;). Lo haremos de la siguiente manera:
sed ‘s/\t/;/g’ fichero
Publicado por Esteban M. Navas Martín en 11:23 3 comentarios Enlaces a esta entrada
Etiquetas: comandos, linux, scripts
El shell de linux: Comando tr
tr es un filtro que nos permite cambiar una determinada información de un archivo por otra.
Cambia cada uno de los caracteres especificados en el conjunto inicial por los caracteres especificados en el conjunto final.
El fichero de origen o fichero destino lo especificamos con los caracteres de redirección: .
Veamos un par de ejemplos o tres:
tr ‘:’ ‘ ‘ ficheropasswd
tr ‘[a-z]‘ ‘[A-Z]‘ listaalumnosmayusculas
tr ‘ ‘ ‘\n’ lineasusuarios
tr -s ” ” prueba2
Parámetros útiles:
* -s : Sustituye un conjunto de caracteres repetidos por uno sólo. Es muy útil cuando hay secuencias de caracteres que queremos borrar:
tr -s ” ” ficherodestino
* -c : Hace que se traduzcan todos los caracteres que no se encuentren especificados en el primer parámetro. En el siguiente ejemplo se traduce por una ? todo lo que no sean letras o números.
tr -c ‘[a-z][A-Z][0-9]‘ ? ficherodestino
* -d : Borra los caracteres que especifiquemos.
tr -d ‘[a-z][0-9]‘ ? ficherodestino
Comando uniq
uniq es uno de los filtros que nos sirve para filtrar o eliminar las líneas repetidas con los que trabajamos bastante.
Podemos darle varios usos. El principal es eliminar lineas repetidas, tal y como hace el parámero -u del comando sort.
* Para visualizar líneas no repetidas no tenemos que indicar ningún parámetro, aunque podemos pasarle el parámetro -u.
* También podemos usar el parámetro -d para visualizar las líneas repetidas.
* También podemos utilizarlo para contar líneas repetidas, pasándole el parámetro -c.
Comando sort
sort es uno de los comandos que utilizamos mucho a la hora de realizar scripts.
Nos permite ordenar los registros o líneas de uno o más archivos.
La ordenación se puede hacer por el primer carácter, por el primer campo de la línea o por un campo distinto al primero en el caso de ficheros estructurados.
Podemos ordenar el contenido de un fichero de la siguiente manera:
sort fichero
Se realizaría la ordenación y el resultado se mostraría por pantalla. Así que, si lo que queremos es obtener el resultado de la ordenación en un fichero, haríamos:
sort fichero > ficheroordenado
Si lo que queremos es ordenar varios ficheros y añadir el resultado a otro, podemos indicar varios ficheros en la línea de entrada:
sort fichero1 fichero2 > fichero3
Y si lo que queremos es ordenar un fichero y dejar el resultado de la ordenación en el mismo fichero, podemos hacerlo con el parámetro -o (output):
sort -o f1 f1
Veamos una lista de los parámetros que pueden resultarnos más útiles a la hora de usar este comando:
* -f : Este parámetro nos sirve para indicar que las mayúsculas y las minúsculas se van a tratar de forma diferente y que por tanto se va a seguir un ordenamiento alfabético.
* -n : Este parámetro nos sirve para ordenar los campos numéricos por su valor numérico.
* -r : Nos permite realizar una ordenación inversa, es decir, de mayor a menor.
* +número : Este parámetro nos sirve para indicar la columna o campo por el que vamos hacer la ordenación.
* –field-separator= separador. Normalmente, se usa como delimitador de campos el espacio en blanco. Podemos utilizar el parámetro –field-separator para indicar que vamos a usar otro delimitador de campo cualquiera. Ej: –field-separator=, La opción abreviada de –field-separator es -t.
* -u : Nos permite suprimir todas las líneas repetidas después de realizar la ordenación.
Y algunos ejemplos con dichos parámetros:
Obtener un listado de los ficheros del directorio actual, ordenado por tamaño de archivo:
$ ls -l | sort +4n
Obtener un listado de los ficheros del directorio actual, ordenado de mayor a menor por tamaño de archivo:
$ ls -l | sort -r +4n
Obtener un listado de los ficheros del directorio actual, ordenado por nombre del archivo:
$ ls -l | sort +7
Ordenar un fichero eliminando las líneas repetidas:
$ sort -u fichero
Ordenar un fichero pen el que los campos están separados por comas, por el campo número 3:
$ sort -t, +3

Comando join
Un comando que nos puede resultar bastante util para mezclar información obtenida de dos ficheros relacionados es el comando join.
join se utiliza para crear un archivo mezclando otros dos que tienen un campo clave con información común. Por defecto, no tenemos que indicar ese primer campo común, pero podemos indicar otro campo distinto.
Para poder mezclar la información de ambos ficheros, los campos deben estar separados por un caracter, que por defecto es el espacio o tabulador.
Ejemplo:
join fichero1 fichero2
Los espacios iniciales se ignoran.
Si deseamos especificar un separador de campo específico, lo hacemos con el parámetro -t. Veamos un ejemplo en el que utilizamos como separador de campos los dos puntos:
join -t”:” profesores.txt grupos.txt
Pero imaginemos que el campo por el que queremos mezclar los ficheros no es el primero en ambos archivos. Pues bien, podemos indicar el número de campo por el que queremos hacer la mezcla en cualquiera de los archivos:
join -t”:” -2 2 profesores.txt grupos.txt
En el ejemplo anterior estamos indicando que la mezcla se debe realizar tomando el primer campo del primer fichero con el segundo campo del segundo fichero.
También podríamos indicar los campos de cada fichero por los que se debe mezclar:
join -t”:” -1 2 -2 2 profesores.txt grupos.txt
En este caso, mezclamos tomando como referencia el segundo campo del primer fichero con el segundo campo del segundo fichero.
Un detalle importante a destacar: Los ficheros deben estar ordenados por el campo que se van a mezclar.
Comando cut
El comando cut nos permite buscar y/o seleccionar columnas o campos dentro de un archivo estructurado.
En el caso de los campos, los archivos deben estar estructurados y entre campo y campo debe existir obligatoriamente un delimitador. Este delimitador puede ser: los dos puntos ( : ), el tabulador, espacio en blanco, u otro carácter.
Para seleccionar un campo dentro de un fichero debemos especificar el número de campo después del parámetro:
cut -f numerodecampo fichero
Por defecto, el delimitador es el tabulador. Si utilizamos otro delimitador, lo indicaremos mediante el parámetro -d . Por ejemplo:
cut -f numerodecampo -d”delimitador” fichero
Si trabajamos con columnas nos encontramos como primera referencia que tenemos campos de longitud fija, mientras que con los campos estos pueden ser de longitud variable.
El número de cada columna hace referencia a su posición dentro de la línea. Indicamos las columnas con el parámetro -c número de columna y fichero. Por ejemplo:
cut -c22-34 fichero

Autor: Esteban M. Navas Martín

No hay comentarios:

Publicar un comentario