0% found this document useful (0 votes)
49 views

Shellprogramming - USalamanca

The document provides an introduction to shell programming in Spanish. It covers topics such as what is a shell, types of shells (Bourne, C, Korn), uses of shells (command interpreter, scripts, programs), shell variables, parameters, input/output redirection, conditions, loops, functions, and arithmetic operations. It also discusses basics of programming in the Bourne shell, including variables, parameters, I/O, conditions, loops, functions, and arithmetic. The document is intended to teach the fundamentals of shell scripting.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views

Shellprogramming - USalamanca

The document provides an introduction to shell programming in Spanish. It covers topics such as what is a shell, types of shells (Bourne, C, Korn), uses of shells (command interpreter, scripts, programs), shell variables, parameters, input/output redirection, conditions, loops, functions, and arithmetic operations. It also discusses basics of programming in the Bourne shell, including variables, parameters, I/O, conditions, loops, functions, and arithmetic. The document is intended to teach the fundamentals of shell scripting.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 150

Programación

en Shell
Rodrigo Santamaría Vicente

Dpto. Informática y Automática


Contenidos

1. Introducción a la shell
2. Programación básica en bash
3. Programación avanzada
4. sed y awk
5. Referencias
Introducción a
la Shell
1.¿Qué es una shell?
2.Tipos de shell
3.Usos de la shell
4.Variables de entorno
¿Qué es una shell?

Interfaz entre el Sistema Operativo y el


usuario
Dos tipos
Gráfica
Línea de Comandos
CLI (Command Line Interface)
intérprete de comandos, terminal, consola

shell (ʃɛl/) – noun 1.a hard outer covering of an animal, as the hard case of a mollusk,
or either half of the case of a bivalve mollusk.
Shell Gráfica
Shell de Línea de Comandos

Generalmente
con shell nos
referimos a una
CLI de Unix
Gráfica vs Texto

Gráfica Línea de Comandos


Sencilla Ciertas operaciones son
Fácil uso más rápidas

Usuario base Usuario experto

Procesamiento de imagen, Transferencia o


video, etc. procesamiento de datos
Tipos de shell
• Bourne shell (sh)
–1977. Stephen Bourne, Bell Labs.
• C Shell (csh)
–1980. Bill Joy, Berkeley
• Korn Shell (ksh)
–1980. David Korn, Bell Labs.
• Bourne again shell (bash)
–1987. Brian Fox, GNU Project
Bourne Shell (sh)

• La más antigua
• No tiene características interactivas
– Historia de comandos
– Autocompletar nombres de ficheros
–…
• No tiene estructuras complejas de
programación
– Funciones
– Case
–…
C Shell (csh)

• Sintaxis como el lenguaje C


– No compatible con la familia Bourne

• Capacidades interactivas
– Pausar/reiniciar procesos
– Historia de comandos
– Operaciones matemáticas
Korn Shell (ksh)

• Sustituye y es compatible con Bourne

• Características interactivas como C, pero


mejoradas
– Añade edición de líneas de la historia
– Ejecución más rápida
Distribuciones

bash csh ksh

linux freebsd solaris

AIX, HP-UX,
mac os X
BSD
POSIX shell

• Similar a ksh y utilizada por HP-UX


• 95% compatible con Bourne shell
• Como ksh, integra características de la csh,
mejoradas (histórico de comandos,
autocompleción, operaciones aritméticas…)
• Las diferencias con bourne shell son menores
• Las diferencias entre POSIX y ksh son mínimas:
– http://docs.hp.com/en/B2355-90046/ch15s03.html
Multiplicidad de las shells

• Ante el mismo sistema operativo, podemos tener


varias shells activas al mismo tiempo
– Gráficas y de texto (Linux)
– De texto en distintos terminales
• $$ indica el PID de la shell en ejecución
• ps para ver los PID de todos los procesos en
ejecución
• $SHELL nos indica el tipo de shell que estamos
usando
• /etc/shells es un fichero con todas los tipos
de shell disponibles en el sistema
Usos de la sh
• Intérprete de comandos: ejecutar comandos
desde el intérprete
• Scripts: ejecutar secuencias de comandos desde
un fichero
• Programas: control del flujo de ejecución de
secuencias de comandos (bucles, condiciones,
variables, etc.) desde un fichero
Intérprete de comandos

• Sintaxis típica
– comando [-]opciones parámetros
• Opciones: dependen de cada comando y alteran
su funcionamiento
• Parámetros: variables de entrada que necesita el
comando, separadas por espacios
– ps –fu
– ls file.txt
– grep “*.txt” ../folder
Procesamiento secuencial

• El sistema completa cada comando antes


de ejecutar el siguiente:
date
ps –fu
who
Procesamiento secuencial

• date; “ps –fu”; who


Procesamiento no Secuencial

• Cada programa se ejecuta sin esperar a que el anterior


termine
date & “ps -fu” & who

date
ps
who

ps
date
who
Redirección de E/S

• > Escribe la salida estándar a fichero


• < Lee la entrada estándar de fichero
• >> Añade la salida estándar a un fichero
existente
• > y >> crean el fichero si no existe
• < da error si el fichero no existe
Tuberías (pipes)

• Conectan la salida de un programa a la entrada del


siguiente
– ls | more  ls > temp; more < temp
Shell script

• Simplemente, poner en un fichero órdenes


que se puedan ejecutar en el intérprete de
comandos
• Para editar el fichero, se puede usar
cualquier editor (típicamente vi)
• Ejemplo: editar un fichero con la línea:
• date; who; ps uf; du /home
• Ejecutar con:
• sh nombreScript
Trucos

• Si se usa vi, lo ideal es tener dos consolas


abiertas, una para edición y otra para ejecución
• Para poder ejecutar un fichero como script,
debemos tener permisos de ejecución
•chmod +x nombreFichero
• Otros modos de ejecución:
– ./nombreScript
– nombreScript si se encuentra en el PATH
Fichero .profile

• Script(s) que se ejecuta automáticamente al


hacer login
• Se encuentran en el directorio raíz del
usuario
• Establece el “entorno” de trabajo

sh bash ksh csh


.profile .bash_profile .profile .profile
.bash_login .kshrc .cshrc
.profile
.bashrc
Variables de entorno

PATH Directorios para la búsqueda de


parámetros, separados por (:)
HOME Directorio raíz de nuestra cuenta
LOGNAME Nombre de cuenta con el que hemos
accedido al sistema
PWD Directorio de trabajo actual
OSTYPE Tipo de Sistema Operativo
PS1 Configuración del prompt de consola
SHELL Shell que estamos usando
Variables de entorno

• Para acceder al valor $VAR


• Para imprimir el valor echo $VAR
• Para cambiar el valor VAR=valor
• Los cambios a las variables de entorno
no se mantienen para otras shells a no
ser que se incluyan en el .profile o se
utilice export
• Ejercicio
– Establecer en el PATH la ruta de la carpeta
donde almacenaremos los scripts
Programación
básica en Bourne Shell
1. Introducción
2. Variables
3. Parámetros
4. E/S
5. Condiciones
6. Bucles
7. Funciones
8. Operaciones aritméticas
9. Depuración
Programación Shell
• Scripts donde introducimos conceptos
propios de la programación
– Variables
– Parámetros
– Condiciones
– Bucles
– Funciones
– Operaciones aritméticas

• Los comandos disponibles de la shell


actúan como nuestra biblioteca de
funciones
Por qué programar en shell?

• Requiere un cierto esfuerzo programar en shell,


así que antes debemos plantearnos si nos va a
ser útil
• Razones para programar en shell
1. Porque nos lo mandan (como es el caso)
2. Porque sabemos programar: el esfuerzo necesario
para aprender es muchísimo menor
3. Porque en nuestro trabajo nos va a ser útil:
– Administradores: tareas complejas o automatizables
– Hackers: tareas rápidas
– Programadores usuarios: tareas que se repiten
Cuándo programar en shell?

• Llamadas frecuentes a funciones del sistema


• Llamadas repetitivas a una función del sistema
• Programas cortos
– Si un programa pasa de una página, probablemente
la shell no sea la mejor solución
• Cuanto mejor conozcamos la shell y sus
comandos, más la usaremos y mayor útil será la
programación en shell
Variables

• Además de las variables de entorno podemos


declarar variables locales al script
• No tienen tipo, no hay que declararlas o
inicializarlas previamente

• Asignación: variable=valor
• Acceder al valor: $variable
Variables (II)

• Para diferenciar el valor de variables en cadenas,


usamos { }:
–dir2=/home/rodrigo/curso
–cat ${dir2}/lista.txt
• Normalmente, se abre una shell para ejecutar el
script
– si queremos que se ejecute en la shell en que
estamos, y así luego tener disponibles las variables,
usamos (.): . programa
Parámetros
• Un script puede tener parámetros de entrada
igual que cualquier comando
–script par1 par2 par3 …
• Para acceder a sus valores usamos
– $1, $2, $3, … $9
• $0 es el nombre del comando
• $*, $@ devuelven todos los parámetros
separados por espacios
Parámetros (II)

• Número de parámetros: $#
• Si tenemos más de 9 parámetros, tenemos que usar
desplazamientos: shift [n]
– Donde n es el número de pasos que desplazamos
– Si no se especifica n, se comporta como shift 1
Gestión E/S: echo
• Salida por consola: echo cadena
Caracteres descripción
especiales
-n Evita el salto de línea
(útil si se espera un parámetro de entrada)
\ Elimina el significado especial del siguiente carácter
“ ” Todo lo que está entre comillas pierde su significado
especial salvo $ y \
‘’ Lo que encierra se toma literalmente
` ` Todo lo que está entre acentos graves se trata como
un comando
echo: secuencias de escape

secuencias descripción
de escape
-e activa la interpretación de secuencias de escape
\a alerta (beep)
\b elimina el carácter anterior (backspace)
\c suprime el salto de línea (como –n)
\n salto de línea
\r retorno de carro
\t tabulador horizontal
\\ barra hacia atrás (\)
echo: códigos de escape

• Se introducen con la secuencia de escape \033


• Cada código tiene la sintaxis: [parametroAcción
– parámetro es un número
– acción es una letra

• Ejemplo:
• echo –e “\033[34m Hola”
echo: códigos (ii)

acciones descripción y parámetros


m modifica el estilo de la fuente
0 – modo por defecto (letras negras, fondo blanco)
1 – negrita
5 – parpadeo
7 – intercambia el color de fondo y el de las letras
11 – acepta caracteres ASCII extendidos (asciitable.com)
25 – deshabilita el parpadeo
27 – deshabilita el intercambio de colores
30-37 – establece el color de las letras (31 rojo, etc.)
40-47 – establece el color de fondo
echo: codigos (iii)

acciones descripción
q gestiona los bloqueos del teclado
0 – apaga todos los bloqueos del teclado
1 – encience el bloqueo de scroll, apaga el resto
2 – enciende el bloqueo de números, apaga el resto
3 – enciende el bloqueo de mayúsculas, apaga el resto
7s Almacena la posición del cursor y sus atributos
8u Recupera la posición del cursor y sus atributos
ojo: 7s y 8u no funcionan en todos los terminales, es más recomentable
usar tput sc y tput rc
H,f Establece la posición del cursor
x;y – posición para el cursor
echo: ejemplos
Gestion E/S: read

• Entrada de consola: read var

• En ksh también se puede hacer así:


•read fich?“Introduce nombre de fichero: ”
Gestión E/S: exit

• Salida del script: exit código_fin


•0 terminado con éxito
•1 error interno
•2 error por sintaxis de llamada
• $? Devuelve el código de salida del último
comando ejecutado
Expresiones regulares
• Manejar con soltura las expresiones regulares es
fundamental para programar en shell y manejar
comandos como grep, sed o awk.

Símbolo Descripción
* La expr. reg. anterior aparece 0+ veces
. Cualquier carácter (1 ocurrencia)
.* Cualquier cadena de caracteres
[ … ] Cualquier carácter de los especificados entre
corchetes, o un rango si separados por ‘-’
[a-z] [0-9] [a-z,A-Z] [Tt]
Expresiones regulares (II)

• Más expresiones regulares


Símbolo Descripción
$ La línea acaba con la expr. reg anterior
^ La línea empieza con la expr. reg. siguiente
^$ Líneas en blanco
[^…] Líneas sin los caracteres entre corchetes
\(…\) Marca expr. regulares, para luego repetirlas
con \n, donde n es la n-ésima expr. marcada
\ Interpretar literalmente el símbolo especial
siguiente
Expresiones regulares (III)

• Extensión POSIX
Símbolo Descripción
? La expr. reg. anterior aparece 0 ó 1 vez
[hc]?at  at, hat, cat
+ La expr. reg. anterior aparece 1+ veces
[hc]+at  hat, cat, hhat, chat,
__________hcat, ccchat
| Aparece la expr. anterior o la posterior
cat|dog  cat, dog
Condiciones

• if lista_condiciones1
• then lista_comandos1
• elif
lista_condiciones2
• then lista_comandos2
•…
• else lista_comandosN
• fi
Test

• Para chequear condiciones se usan [ ] en la


sintaxis del if (equivalente al comando test)

-eq, = Igual a
-lt Menor que
-gt Mayor que
-le Menor o igual que
-ge Mayor o igual que
Test

Ficheros
-f fich Verdadero si fich existe y es un fichero

-r fich Verdadero si fich existe y se puede leer

-w fich Verdadero si fich existe y se puede escribir

-x fich Verdadero si fich existe y se puede ejecutar

-d fich Verdadero si fich existe y es un directorio

-s fich Verdadero si fich existe y tiene tamaño


mayor que cero
Test

Cadenas
-n cad Verdadero si cad no es una cadena nula
-z cad Verdadero si cad sí es una cadena nula
cad1==cad2 Verdadero si las cadenas son iguales
cad1!=cad2 Verdadero si las cadenas son distintas
cad Verdadero si cad existe y no tiene valor nulo
Test

Operadores booleanos
-a AND
-o OR

• Observaciones
– Incluir siempre un espacio despues de [ y antes de ]
– test solo vale para enteros, los reales son truncados al
entero más próximo
Case

• Expansión de if (similar al switch de C


o java)
•case param in
•patron1 [ | patron2…] )
lista_comandos1 ;;
•patron2 [ | patron3…] )
lista_comandos2 ;;
•…
•esac
Case
Ejercicio

• Hacer un script similar a mv, move, con


la siguiente sintaxis
» move filename
• Deberá:
1. Chequear si hay argumento y salirse si no,
mostrando la sintaxis correcta
2. Chequear que el argumento es un fichero
3. Preguntar si se quiere mover el fichero a otro
directorio o cambiarle el nombre
4. Proceder en cada caso, pidiendo el nombre
nuevo para el fichero o el directorio al que se va
a mover y realizar la operación (mv)
Ejercicios

1. Modificar move para que el paso 3 se haga


mediante case

2. Hacer un programa showLines que muestre num


líneas de un fichero empezando en start
– showLines start num file

3. Hacer un programa sayHello que diga “Buenos


dias”, “Buenas tardes” o “Buenas noches”, seguido
del nombre del usuario, según la hora que sea. El
programa debe ejecutarse automáticamente al abrir
un terminal
Bucles
• For
•for parametro [ in lista]
•do lista_comandos
•done
•parametro toma los valores de la lista y
para cada uno de ellos se ejecuta
lista_comandos
• Si se omite la lista, parametro contiene los
parámetros de entrada al script ($1 $2 …)
for (ii)
for (iii)

• Sintaxis como en C:
– for (( expr1; expr2; expr3 ))
– do
–…
– done

• Ejemplo:
– for (( i = 0 ; i <= 5; i++ ))
do
echo “Hola $i veces"
done

While

• Ejecutamos lista_comandos2 mientras la


siguiente entrada de lista_comandos1
tenga éxito (código de salida 0):

•while lista_comandos1
•do lista_comandos2
•done
Until

• Como while, pero se ejecuta hasta que la


condición sea verdadera, en vez de
mientras la condición no sea falsa

•until lista_comandos1
•do lista_comandos2
•done
Ejemplos while - until
Detalles

• echo ^G produce un “beep”

• break rompe un bucle for o while

• # a comienzo de línea para añadir un comentario

• $$ devuelve el identificador único de la shell


Ejercicios

1. Hacer un script gp (groupcopy), que


copie todos los ficheros del directorio
actual al directorio especificado, con la
siguiente sintaxis:

– gp [-q] [-d]
directorioDestino
» -q para confirmar la copia de cada fichero
» -d para incluir ficheros en los
subdirectorios
Ejercicios

2. Realizar un script digitalClock que muestre


la hora cada segundo (función sleep), siempre
en la misma posición (fila 0 y columna 69)
Funciones
• nombreFuncion() {listaComandos;}
– Valor de retorno: return n
– Llamada: nombreFuncion
parametros
•parametros es una lista separada por espacios

• OJO: Los parámetros posicionales ($1, $2, …) se convierten en los


parámetros de la función que se llama, perdiéndose los valores
originales.
• OJO: Una funcion debe declararse al principio del fichero, o al menos
antes de su primera llamada
Funciones (II)

No hay que declarar Toma los parámetros como si fuera


parámetros el script principal

Los valores que se


devuelven son
numéricos y siguen
el mismo código de
retorno

No olvidar el ;
Alcance y Biblioteca de funciones

• Cualquier variable declarada en un punto o función del


programa es acessible en cualquier otro punto o
función
– No hay definición de alcance más que para los parámetros
posicionales $1, $2, …

• Las funciones de un script puede utilizarse en otros


scripts utilizando el comando
• . ./script.sh
• La función se invoca como si estuviera en nuestro
script
expr

• expr expresion1 operador expresion2


• expr se puede sustituir por (( … ))
• Realiza operaciones aritméticas

operador acción
+, - Suma, resta
\*,/,% Multiplicación, división, resto
=,!=,\>,\>=, Comparación de enteros
\<,\<=
expr

• Y operaciones con cadenas

expresión acción
expr c1 : c2 Nº de caracteres en que coinciden c1 y
c2 (pueden ser expresiones regulares)
expr length c1 Nº de caracteres de c1
expr index c1 c Posición de la primera ocurrencia del
carácter c en c1
expr substr c1 Subcadena de c1 que empieza en la
start length
posición start y de longitud length
Ejercicios

• Hacer un script fact que devuelva el factorial de


un número que se pasa como argumento
– Sintaxis: fact num
ejercicios

• Programar una función box con la siguiente sintaxis


– box(x,y,alto,ancho)
• Debe dibujar un cuadrado en pantalla como en el siguiente
ejemplo: box(20,5,7,40)
wait y sleep

• wait [n]
– Espera hasta que el proceso con id n acabe
– Si no es especifica id, espera a que todos los
procesos hijos en background terminen
– “!” da el id del último proceso lanzado en segundo
plano  wait $! para esperar por él
• sleep n
– El script se queda bloqueado sin hacer nada durante
n segundos
Depuración
• sh –v script
• Escribe cada linea de código que ejecuta:

$ sh -v suma.sh 4 5
– tot=`expr $1 + $2`
tot=`expr $1 + $2`
– echo $tot expr $1 + $2
echo $tot
9
Depuración de scripts

• sh –x script
• Sustituye cada $var por su valor
• Muestra cada línea de código que se va
ejecutando
– Precedida de +, o de ++ si es un subcomando de la
línea
$ sh -x suma.sh 4 5
– tot=`expr $1 + $2` ++ expr 4 + 5
– echo $tot + tot=9
+ echo 9
9
Programación
avanzada en bash
1. Variables locales y globales
2. Señales
3. getopts
4. Utilidades esenciales
Variables globales y locales

• Las variables declaradas en un programa son


locales, y por tanto no estarán disponibles en
otras shells
• Para hacer global: export var
$ vech=Bus
$ vech=Bus
$ echo $vech
$ echo $vech
Bus
Bus
$ /bin/bash
$ export vech
$ echo $vech
$ /bin/bash
$ vech=Car $ echo $vech
$ echo $vech Bus
Car $ exit
$ exit $ echo $vech
$ echo $vech Bus
Bus
Ejecución condicional

• comando1 && comando2


– Ejecuta comando2 sólo si comando1 se ejecutó con
éxito
• comando1 || comando2
– Ejecuta comando2 sólo si comando1 se ejecutó sin
éxito
• listaComandos1 ; listaComandos2
– Se ejecuta primero listaComandos1, luego
listaComandos2
– test –d /tools && cd /tools; test –z “$fn” || sort
–o $fn $fn &
Señales

• Un programa puede terminar de manera forzosa


debido a un error en el SO o a la interrupción por
parte del usuario
• Para avisar de ello, se utilizan señales
• Si, por ejemplo, un programa modifica ficheros
delicados o crea ficheros temporales, etc. debe
manejar la gestión de señales para evitar dejar
ficheros incompletos o innecesarios
Trap

• trap {comandos} {lista de ids. de señal}


• Ejecuta la lista de comandos cuando se produce
alguna de las señales especificadas
• Una vez incluida, se mantiene a la escucha para
el resto del programa
• Es bueno tratar estas señales en una función,
que será la que se incluya en trap como
comando
ids. de señal

nº de señal ocurre cuando


0 salida de la shell
1 hangup (colgar)
2 interrupt (ctrl+C)
3 quit
9 kill (no se puede coger con trap)
15 terminate (kill que se puede coger con trap)

Existen muchas más señales (segmentation fault, bus error, power fail,
etc) , pero generalmente, estas son las que se busca controlar
Señales: ejercicio

• Hacer un programa ages que


1. Acepte un único parámetro, el nombre de un
fichero
2. Indefinidamente:
1. Pregunte por un nombre y luego por una edad
2. Añada el nombre y la edad a un fichero temporal temp
3. Pregunte si se quieren añadir más ficheros
4. Si no se van a añadir más ficheros, vuelca temp al
fichero que se pasó como parámetro
3. Ejecutar el programa, meter un par de nombres y
luego pulsar CTRL+C
Señales: ejercicio (II)

• ¿Qué ocurre? temp no se ha borrado y no se ha


generado el fichero final
• Hacer tratamiento de la señal generada por
CTRL+C para que temp se borre en ese caso.
señales: ejercicios (iii)

• Modificar el programa fantasticCar para que


gestione correctamente su terminación
– Deberá escuchar por la señal de terminación y
termine el programa dejando todos los leds como
estuvieran y despidiéndose con “Buenos días,
Michael”
getopts
• getopts optstring var1
• Recoge las opciones que se le hayan pasado al
script y que coincidan con la sintaxis en
optstring, almacenándolos en var1
• Si un parámetro en optstring va seguido de :
quiere decir que requiere de un argumento
• Ejemplos para optstring:
–n:asgr:t
–-n argn –a –s –g –r argr –t
–-n argn –r argr -asgt
getopts (II)

• Si una opción requiere de argumento, se


almacena en $OPTARG
• $OPTIND es el índice del siguiente parámetro
• Ejemplo: usage: civilState –n name –a age -s
• while getopts n:a:s opt
do
case "$opt" in
n) na="$OPTARG";;
a) age="$OPTARG";;
s) single=“y” ;;
esac
done
getopts: ejercicios

1. Modificar el programa move para que los


parámetros sean recogidos mediante getopts
– usage: move [–f file | -d dir] filename
2. Escribir un script utilities que, mediante
getopts, comprenda la sintaxis
– usage: utilities –c –d –e editor
– -c limpia la pantalla
– -d muestra la lista de ficheros en el directorio
actual
– -e inicia el editor que se pase como parámetro (p.
ej, vi), comprobando si existe antes
Utilidades esenciales
• Linux provee una serie de utilidades esenciales
para agilizar el trabajo:
– Ficheros de datos
– Información del sistema
– Administración del sistema
Ficheros

• Vamos a trabajar sobre dos ficheros sencillos


sname smark
(nombres) (patrimonio en mill.)
Sr.No Name Sr.No Mark
11 Vivek 11 67
12 Renuka 12 55
13 Prakash 13 96
14 Ashish 14 36
15 Rani 15 67
cut

Extracción de columnas o campos: cut


– cut [opciones] [fichero ...]
Opciones
-c lista Trata cada carácter como una columna
-f lista Campos delimitados por tabuladores
-d SEP Utiliza el carácter SEP como separador en vez del
tabulador
lista es una secuencia de números para indicar qué
campos o columnas se quieren cortar:
A-B Campos o columnas A hasta B inclusive
A- Campo o columna A hasta el final de la línea
A,B Campos o columnas A y B
paste

• Pegar líneas de ficheros por columnas


• paste file1 file2
• Como separador, añade un tabulador
$ paste sname smark
11 Vivek 11 67
12 Renuka 12 55
13 Prakash 13 96
14 Ashish 14 36
15 Rani 15 67
• Ejercicio: Generar un fichero con códigos, patrimonio
y nombres, pero sin repetir el código de persona
cut –f2 smark > temp; paste sname temp; rm temp
join

• Pega líneas de dos ficheros, por columnas, sólo si


tienen campo de la primera columna con el mismo
valor
– join file1 file2
$join sname smark
11 Vivek67
12 Renuka 55
13 Prakash 96
14 Ashish 36
15 Rani 67

• Si uno de los campos no existe en alguno de los


ficheros, no lo añade
tr

• Cambiar un rango de caracteres a otro distinto


–tr pattern1 pattern2

$ tr "h2" "3x" < sname $ tr "[a-z]" "[A-Z]"


11 Vivek hola
1x Renuka HOLA
13 Prakas3 …
14 As3is3
15 Rani
tr (ii)

• Opciones
opciones descripción
-s elimina espacios en las secuencias encontradas
-c añade pattern2 a pattern1 en vez de sustituirlo
-d elimina pattern1 (no se necesita pattern2)
uniq

• Elimina líneas duplicadas adyacentes


– uniq file
• -c indica el número de veces que aparece duplicada
• Su salida es el mismo fichero sin líneas
duplicadas adyacentes
• Si queremos eliminar todas las líneas
duplicadas
– sort file | uniq
Ejercicios con ficheros

• Hacer un script listWords que recoja todas


las palabras de file1 y las ordene en una lista
de palabras (sin repetir), según la cantidad de
veces que aparecen (que debe aparecer en la
lista), que se guardará en file2
– listWords file1 file2
• Modificar el script para que acepte la opción –
v, en cuyo caso la ordenación se llevará a cabo
según palabras que rimen
– truco: usar rev
ejercicios

• Un digrama es un conjunto de dos palabras.


Realizar un script que liste, en orden, el número
de ocurrencias de cada digrama en un fichero
que se pase como parámetro
•listDigrams file1 file2
awk y sed
a) sed b) awk
1. substituciones 1. patrones
2. delimitadores 2. acciones
3. marcadores 3. variables
4. ocurrencias 4. scripting
5. scripting 5. nawk
6. restricciones
sed
• stream editor: edición de textos en script
–sed –e ‘expr1’ [–e ‘expr2’ …] filename
• sed suele estar muy mal documentado:
– http://www.grymoire.com/Unix/Sed.html#uh-0
• Si sólo se usa una expresión, se puede quitar el
–e: sed ‘expr1’ filename
• Si no se pone filename, se usa la entrada
estándar
sed - substitución

• sed ‘s/word1/word2/’ filein>fileout


• Substituye word1 por word2 en filein y lo
escribe en fileout
• Si no se especifica fileout, lo escribe en
consola
• Ejemplo: sed ‘s/gold/stone/’ coins.txt>
• La substitución es la operación más común para
la que se usa sed
• word1 y word2 pueden ser expresiones
regulares
sed - delimitadores

• El delimitador (/) puede cambiarse por cualquier


otro carácter que no aparezca en las palabras
• Ejemplo: sustituir rutas de fichero
– sed 's|/usr/local/bin|/common/bin|' old >new
– sed 's:/usr/local/bin:/common/bin:' old >new
– sed 's_/usr/local/bin_/common/bin_' old >new
&

• & indica la cadena correspondiente al patrón


buscado
• Útil cuando no sabemos exactamente qué
estamos buscando (expresiones regulares):
– Poner paréntesis a cualquier palabra en minúscula
sed 's/[a-z]*/(&)/' old >new
– Duplicar el primer número de cada línea
– echo "123 abc" | sed 's/[0-9]*/& &/'
– echo "abc 123" | sed 's/[0-9]*/& &/‘  ?
– echo "abc 123 456" | sed 's/[0-9]*/& &/‘  ?
substitución global

• sed sólo modifica la primera ocurrencia de la


expresión buscada en cada línea
• para modificar todas las ocurrencias
–‘s/pattern1/pattern2/g’

• echo "abc 123 456" | sed 's/[0-9][0-9]*/& &/g‘


flags (marcadores)

• Podemos marcar los patrones con \(…\)


• Un patrón marcado se puede repetir con \1, \2…
según el orden en que se hayan marcado (hasta \9)
• Quedarnos con la primera palabra de cada línea:
– sed 's|\([a-z]*\)*|\1|'
• Cambiar el orden de la primera y la segunda palabra
– sed 's|\([a-z]*\) \([a-z]*\)|\2\1|'
• Eliminar palabras duplicadas
– sed 's|\([a-z]*\) \1|\1|'
• probar con echo “perro perro gato”
• y con echo “casa perro gato”?
ocurrencias

• /n especifica a qué ocurrencia del patrón nos


referimos
• Eliminar la segunda palabra de cada línea
• echo "casa perro gato " | sed 's/[a-z][a-z]* //2'
• Comparar con
• echo "casa perro gato " | sed 's/[a-z][a-z]* //'
• echo "casa perro gato " | sed 's/[a-z][a-z]* //g'
• /n se puede combinar con g:
• echo "casa perro gato " | sed 's/[a-z][a-z]* //2g'
escribir a fichero

• sed ‘s/word1/word2/w file’ filein


• No tiene mucho sentido si solo tenemos una
expresión (es equivalente a >file)
• Es muy útil si tenemos varias expresiones y
queremos que la acción de cada una vaya a un
fichero diferente
• En caso de que se usen varias opciones tras el
último /, w debe ser la última.
sed scripting

• Cuando tenemos muchas expresiones sed, es


cómodo hacer un sedscript:
•#Este script cambia vocales minúsculas
a mayúsculas
•s/a/A/g
•s/e/E/g
•s/i/I/g
•s/o/O/g
•s/u/U/g
• Para llamarlo: sed –f script filein>fileout
sed en shell script

• Dentro de un shell script, podemos usar


igualmente sed. Podemos utilizar varias líneas
usando “\”
•sed -e 's/a/A/g‘ \
-e 's/e/E/g' \
-e 's/i/I/g' \
-e 's/o/O/g' \
-e 's/u/U/g' filein >fileout
paso de argumentos
a sed en shell script
• Deberemos jugar con las comillas para que no
tome el argumento como una expresión regular:

• sed -n 's/'$1'/&/g'

• Para evitar problemas de sintaxis en el caso de


que el parámetro contenga espacios:

• sed -n 's/‘“$1”'/&/g'
restricciones

• Restringir a una línea


• sed ‘n s/searh/replace/options’
filein>fileout
• Restringir a un rango de líneas
• sed ‘n,m s/searh/replace/options’ filein>fileout

• La última línea del fichero se identifica con $


• Restricción con patrones: la búsqueda va de la
primera línea en la que se encuentre p1 hasta la
primera en que se encuentre p2
• sed ‘/p1/,/p2/ s/searh/replace/options’ fin>fout
otras opciones

• sed tiene multitud de opciones adicionales


– manejo de E/S
– condiciones (if, else)
– control de flujo (for, while)
– etc.
• Sin embargo, para soluciones más complejas
que búsquedas y sustituciones simples, awk es
más potente y más fácil de utilizar
otras acciones

acciones significado
q quit (terminar la ejecución)
p print (imprime por pantalla la salida de sed)
w write (escribe a fichero la salida de sed)
Ejercicios

1. Sustituir todas las vocales minúsculas de un


fichero por vocales mayúsculas
2. Realizar el mismo ejercicio, pero mediante un
sedscript llamado vowels
3. Realizar el mismo ejercicio, pero en una
shellscript
4. Modificar 3 para que se acepten los nombres
de ficheros de entrada y salida como
argumentos
ejercicios (ii)

5. Queremos cambiar todos los ficheros con


extensión *.txt a *.tex. Hacer mv *.txt
*.tex no funciona ¿Por qué? Hacer un script
basename que realice esta función
awk
• Se puede ver como
– Utilidad para realizar procesamiento sencillo de texto
– Lenguaje de programación para procesamiento
complejo de texto
• Basado en C
• Utilizado para
– Generación de informes
– Manejo de Bases de Datos pequeñas
– Traducir formatos de fichero
– Realizar operaciones matemáticas en ficheros
numéricos
awk (ii)

• AWK  Aho, Weinberg & Kernigan


– Kernigan es autor, junto con Ritchie, de C
• AWK es un lenguaje interpretado
– Relativamente lento
– Fácil de apreder
• AWK cuando no haya una solución más sencilla:
– grep para buscar texto
– head/tail para quedarnos con partes de texto
– cat, paste, join para unir ficheros
– sed para hacer búsquedas/reemplazos
– tr, unique, sort para transformaciones básicas
Fichero de ejemplo: coins.txt

metal weight_in_ounces date_minted country_of_origin description

gold 1 1986 USA American Eagle

gold 1 1908 Austria-Hungary Franz Josef 100 Korona

silver 10 1981 USA ingot

gold 1 1984 Switzerland ingot

gold 1 1979 RSA Krugerrand

gold 0.5 1981 RSA Krugerrand

gold 0.1 1986 PRC Panda

silver 1 1986 USA Liberty dollar

gold 0.25 1986 USA Liberty 5-dollar piece


sintaxis

• Aplicar a un fichero un patrón awk


• awk [-F<del>]‘/search_pattern/ {awk_actions}’ filename
– Aplica awk_actions a todas las líneas de filename que cumplan con
search_pattern
– -F<del> especifica el carácter a utilizar como delimitador de
columnas. Por defecto, se toman espacios y tabuladores
• Aplicar a un fichero un programa awk
• awk –f awk_program filename
• Básicamente ambas opciones son lo mismo, la
segunda se usa cuando el patrón awk se hace
muy largo o lo tenemos en un fichero
patrones de búsqueda
• awk busca en el fichero de entrada todas las líneas
que contengan el patrón de búsqueda
• Patrones de búsqueda
– /seq/ busca líneas que contengan seq
• var ~ /seq/ busca variables (ver +abajo) que contengan seq
– BEGIN busca la primera línea
– END busca la última línea
• Si no se especifica patrón de entrada, devuelve todas
las líneas del fichero
• Las secuencias de búsqueda pueden llevar
metacaracteres
metacaracteres

meta significado
caracter
. Cualquier carácter (uno)
* El carácter anterior aparece 0+ veces
^ Coincide con el comienzo de línea
$ Coincide con el final de línea
\ El carácter siguiente no es metacaracter
[ ] Coincide con alguna de los caracteres entre []
{ } Coincide con la expresión exacta entre {}
+ El carácter anterior aparece 1+ veces
? El carácter anterior aparece 0 ó 1 vez
| Coincide con el patrón a su izquierda o derecha
ejemplos de búsqueda

patrón resultado
/The/ “The”
/^The/ “The Bourne Ultimatum”, “The”, “Thelema"
/The$/ “Bourne Ultimatum, The”, “The”, “Pathe”
/\$/ “$”
/[Tt]he/ “The” “the”
/[a-z]/ “plane” “house” “bourne”
/[a-zA-Z0-9]/ “bourne” “Bourne” “oceanic815”
^[^a-z] “Bourne” “815oceanic”
/{^Germany}/ “Germany” “Germany’s politics …”
ejemplos de búsqueda (ii)

patrón resultado
/wh./ “who” “why” “wh3” …
/wh*/ “w“ “wh” “whh” “whhh” …
/.*/ Cualquier cadena de caracteres
/wh?/ “w” “wh”
/wh+/ “wh” “whh” “whhh” …
/^[+-]?[0-9]+$/ Cualquier entero (con o sin signo)
/^…$/ La línea coincide exactamente
[-+]? Posible signo inicial
[0-9]+ Cualquier cadena de números
acciones

• awk ‘/search_pattern/ {awk_actions}’ filename


• Podemos tener cualquier tipo de acción que ofrezca awk
como lenguaje de programación (~C)
– Asignación de variables y arrays (=)
– Operaciones aritméticas simples (+,-,*,/,%, ++, --, ^)
– Comparaciones aritméticas (==,!=,>,<,>=,<=)
– Operaciones aritméticas avanzadas (sqrt, log, exp, int)
– Salida por pantalla (print y printf)
– Procesamiento de cadenas (substr, split, index, length)
– Estructuras de control (if…else, for, while)
• For se puede usar como en bash: for(var in lista) o como en C
acciones

acción descripción
substr(str,start, substr("unforgettable",6,3)  “get”
length)
split(str, array split(“jay:bob”,c,”:”)
[,sep])
 c[1]=jay, c[2]=bob
index(str, str) index(“gorbachov”, “bach”)  4
index(“gorbachov”, “z”)  0
next salta a la siguiente línea de texto
length(str) devuelve la longitud de la cadena
break, continue, exit Como en shell y C
print y printf

acción descripción
print imprime la linea actual
print imprime “cad1 cad2”
“cad1”,”cad2”
print “cad1” imprime “cad1cad2”
“cad2”
printf() imprime siguiendo la sintaxis de C:
%d, %f, %o, %x
%n.m
\n, \t
variables
• No tienen tipo ni hay que declararlas
• Se asignan como en los programas de la shell
• Variables especiales:
variable descripción
$1, $2, $3… Variable de campo, da el valor de la
columna 1, 2, 3 …
$0 Contiene el valor de toda la línea
NR Número de líneas de entrada
NF Número de columnas
$NF Valor de la última columna
variables especiales (ii)

variable descripción
FILENAME Nombre del fichero de entrada
FS Separador de columnas. Por defecto es
“white space”, refiriéndose a “[ ]“ y “\t”
También se puede modificar con la opción de comando
–F seguido del delimitador (-F:, -F/)

RS Separador de filas. Por defecto es


“newline”, refiriéndose a “\n”
OFS, ORS Como los anteriores pero para el fichero
de salida
OFMT Formato numérico. Por defecto “%.6g”
arrays

• Sólo tienen una dimensión


• El acceso se identifica por indices
–array[1], array[2], array[3]
– Los índices van de 1 a N
• Podemos usar como índices cadenas:
– array[“Roberto”], array[“Antonio”], array[“Luis”]
– En este sentido, se pueden utilizar los arrays como tablas
hash
• Para acceder a cada elemento de un array
– for (i in array) print $i
Ejemplos

• Imprimir todas las líneas con la palabra “gold”


– awk ‘/gold/’ coins.txt
• Imprimir todas las líneas de coins.txt
– awk ‘{print}’ coins.txt
• Imprimir la tercera columna de coins.txt
– awk ‘{print $3}’ coins.txt
• Guardar la tercera columna de las líneas de coins.txt
que contengan la palabra “gold” a un fichero
goldYear.txt
– awk ‘/gold/ {print $3}’ coins.txt > goldYear.txt
Ejemplos

• Hacer doble espaciado en coins.txt (poner una


línea en blanco tras cada línea)
–awk ‘{print ; print “ “}’ coins.txt
• Hacer doble espaciado SIN duplicar líneas en
blanco
– awk {print ; if(NF>0) print “”} coins.txt
• Contar el número de líneas en el fichero
–awk ‘END {print NR}’ coins.txt
–wc coins.txt
Ejemplos

• Imprimir el tamaño medio de los ficheros de


nuestro directorio actual
• ls -l | awk '{count+=$5} END {print count/(NR-1)}‘
• Generar los 10 primeros números de la secuencia
de Fibonacci: 1 1 2 3 5 8 13 21 34 55
» awk 'BEGIN
» {
» a=1; b=1;
» count=0;
» while(count++<10)
» {print a; ta=a; a=b;
b=b+ta;}
» }'
Scripts con awk

• Hacer un script que se llame words, que escriba


cada palabra en el fichero pasado como
parámetro en una nueva línea
– awk ‘NF>0 {split($0, c); for(i in c) print $i}’ $1

– awk ‘BEGIN {FS=“[^A-Za-z]+”}


– {for(i=1;i<=NF;i++) print $i}’ $1
Programas awk
• Un programa awk tiene el siguiente aspecto:
• search_pattern1 {awk_actions1}
search_pattern2 {awk_actions2}
•…
• search_patternN {awk_actionsN}
• Se llama con:
•awk –f awk_program filename
Ejemplo programa awk: findDup

• Buscar palabras seguidas duplicadas en un fichero

• BEGIN { dups=0; w="xy-zzy" }


• {
• for( n=1; n<=NF; n++)
• {
• if ( w == $n )
• {
• print w, "::", $0 ;
• dups = 1
• }
• w = $n
• }
• }
• END { if (dups == 0)
• print "No duplicates found."
• }
Ejercicios

1. Modificar findDup para que muestre el


número de línea en el que se produce el
duplicado
2. Modificar findDup para que no cuente la
última palabra de la línea anterior
Condiciones

• En vez de patrones de búsqueda, podemos usar


condiciones.
• Ejemplo: buscar líneas con el nº diez en su
segundo campo, e imprimir la línea siguiente
•BEGIN {flag = 0}
•$2 == 10 {flag = 1; next}
•flag == 1 {print; flag = 0; next}
• ¿Cómo modificar para que acepte cualquier
número en vez del 10 como parámetro?
ejercicios: bases de datos

• Trabajando sobre el fichero cars.txt


1. Buscar todos los coches de la marca volvo
2. Mostrar la columna 3, seguida de la 1
3. Mostrar todas las entradas que contengan una ‘h’
en la primera columna
4. Mostrar todas las entradas cuya primera columna
empiece con una ‘h’
5. Mostrar la columna 2, luego la 1, luego un ‘mpg’
seguido de la columna 3; sólo para aquellas
entradas cuya seguna columna empieza por m o t.
¿Se observa algo raro?
ejercicios (ii)

6. Mostrar las entradas cuya columna 5 tiene un


valor numérico menor o igual a 100
7. Mostrar todas las entradas desde la primera
que contenga ‘toyota’ hasta la primera que
contenga ‘chevrolet’

8. Mostrar todos los usuarios del sistema que no


tengan como shell por defecto /bin/sh
script con awk

• En shell script, los parámetros de la función


están en $1, $2, $3 …

• En awk, $1, $3, $3 … expresan campos!

• Si queremos usar parámetros del script en


llamadas a awk, antes tenemos que
almacenarlos en otras variables
Ejemplo awk script

• Ejemplo: hacer un script que, mediante awk, devuelva


un campo de un fichero. Campo y fichero deben ser
parámetros del script
»file=$1
»num=$2
»awk '{print $'$num'}' $file
»awk '{print $' $2 '}' $1
• En estos casos, no podemos usar awk –f y
tener el programa awk en otro fichero, pues no
podríamos pasarle los parámetros de la script
Ejercicios awk scripts

• Un palíndromo es una palabra que es igual si se


escribe de izquierda a derecha que al revés.
Buscar todos los palíndromos que se encuentran
en un texto. El script tendrá la sintaxis:
–palindrome filein fileout
ejercicios (ii)

• Hacer un script que devuelva todas las palabras


de un fichero (sin repetir) que tengan tantas letras
como se le indique. El script debe tener la sintaxis
– textAnalysis –l n file
• donde n es el número de letras
• file es el fichero de entrada
nawk

• awk está diseñado para hacer programas cortos


• pero mucha gente lo adoptó como lenguaje de
programación al uso y desarrollaba con él
• nawk (new awk) trata de incorporar herramientas
para una mejor gestión de programas largos
– Funciones
– Entrada: getline
– Trigonometría: sin, cos, atan2, rand, srand
– Manejo de cadenas: match, sub
otras versiones
e implementaciones
• bkw: versión de Brian Kernigan de awk
• gawk: implementación GNU de awk
– No funciona en todos los sistemas
– xgawk: projecto SourceForge que extiene awk con la carga
de bibliotecas dinámicamente
• mawk: implementación muy rápida de awk por Mike
Brennan, basado en un intérprete de código binario
– awka: traductor de awk a C basado en mawk.
• tawk: compilador de awk para DOS y Windows de
Thompson Automation Software
• jawk: implementación de awk en Java
shell y awk en la historia
de la programación
http://www.oreilly.com/news/graphics/prog_lang_poster.pdf
referencias

• Tutoriales utilizados
– shell scripting
• http://www.cyberciti.biz/nixcraft/linux/docs/
uniqlinuxfeatures/lsst/
• http://tldp.org/LDP/abs/html/index.html
– sed
• http://www.grymoire.com/Unix/Sed.html#uh-1
– awk
• http://cs.sru.edu/~whit/cpsc207/notes/awkegs.html
• http://www.vectorsite.net/tsawk_1.html#m1
referencias (ii)

• Libros
– Shells: User’s Guide. Hewlett Packard,
1991
– Linux & Unix Shell Programming. David
Tansley
– Portable Shell Programming. Bruce Blinn
– Unix Shell Programming. Stephen G.
Kochan and Patrick H. Wood

– sed & awk. Dale Dougherty and Arnold


Robbins
– awk Programming. Arnold Robbins
– The AWK programming language. Aho,
Kernigan y Weinberger, 1988, Addison-
Wesley.

You might also like