Crud en AWK

CRUD son las siglas para Create, Read, Update, Delete que son las operaciones básicas de una base de datos relacional. Si por alguna razón, nuestra base de datos es un archivo separado por tabs, texto, o enumerado, podemos utilizar AWK para utilizarlo como un sistema sencillo de base de datos. Para esto, tenemos que garantizar que podemos llevar a cabo las operaciones CRUD. Una restricción más que pondremos es que trataremos que el resultado se guarde en el mismo archivo.

Tomemos como ejemplo un archivo separado por comas que sea un directorio de personas con detalles de contacto y detalles personales.

NAME:LASTNAME:SEX:AGE:SSN:DOB
Abdulrahman:Anthony:M:24:529-77-5347:1996-03-25
Aliza:Beard:F:19:574-05-3881:2000-01-08
Jaidan:Palacios:M:32:624-56-8638:1986-07-16
Juliet:Carrillo:F:37:334-01-6227:1984-11-25
Chardonnay:Boyle:F:41:467-91-5185:1979-05-22
Audrey:Ewing:F:26:261-05-5166:1994-12-14
Abdul:Carver:M:28:473-66-6339:1991-10-03
Sheldon:Jensen:M:21:672-18-6509:1999-07-29
Abdulahi:Petersen:M:28:192-20-5853:1992-02-17
Isabella:Delaney:F:36:313-19-1866:1984-08-04
Milli:Wood:F:32:502-22-5977:1987-07-11
Bob:Garner:M:27:681-16-1585:1993-05-24
Levi:Buchanan:M:29:427-37-3210:1991-10-30
Elle:Parra:F:29:382-26-2505:1990-04-16
Glen:Thornton:M:30:501-98-4486:1989-07-08
Jakob:Mcnally:M:40:656-14-2191:1980-02-02
Sallie:Krueger:F:45:322-96-5004:1976-01-31
Eleasha:Brook:F:39:431-70-3699:1981-11-22
Earl:Mora:M:38:006-88-7685:1982-10-13
Lacey-Mai:Kearney:F:43:574-46-7816:1977-12-10

Create

Para crear un nuevo registro, tenemos dos opciones: crearlo al final, o insertarlo antes o después de algún registro en específico.

Insertaremos el registro Bob:Howard:M:41:429-19-5982:1979-04-26

Para insertar al principio

#!/bin/gawk
# PROGRAMA: crud-create-top.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-12
# PROPOSITO: Insertar registro al principio de un archivo con awk

BEGIN { FS=":"; OFS=":"}
NR == 2 { print "Bob:Howard:M:41:429-19-5982:1979-04-26" }
{print $0}

Para insertar al final

#!/bin/gawk
# PROGRAMA: crud-create-end.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-12
# PROPOSITO: Insertar registro al final de un archivo con awk

BEGIN { FS=":"; OFS=":"}
{print $0}
END { print "Bob:Howard:M:41:429-19-5982:1979-04-26" }

Para insertar en una posición específica

Vamos a insertar el registro de Bob antes del registro con NSS = 427-37-3210

#!/bin/gawk
# PROGRAMA: crud-create-ins-bef.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-12
# PROPOSITO: Insertar registro despues de otro de un archivo con awk

BEGIN { FS=":"; OFS=":"}
/427-37-3210/ {print "Bob:Howard:M:41:429-19-5982:1979-04-26" }
{ print $0 }

Vamos a insertar el registro de Bob después del registro con NSS = 427-37-3210

#!/bin/gawk
# PROGRAMA: crud-create-ins-aft.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-12
# PROPOSITO: Insertar registro despues de otro de un archivo con awk

BEGIN { FS=":"; OFS=":"}
/427-37-3210/ {print $0; print "Bob:Howard:M:41:429-19-5982:1979-04-26"; next }
{ print $0 }

Read (Leer)

Para leer lo que nos interesa es por ejemplo, poder consultar por una llave o condición en específico que nos regrese un registro o grupo de registros.

Esto lo podemos hacer con el patrón al inicio o con un if.

Filtrado con expresiones regulares (match completo)

/Bob/ { print $0 }

Match parcial

BEGIN{ FS=":" } 
$1 ~ /Abd/ { print $0 }'

Podemos filtrar con un campo, por ejemplo filtramos sólo a las mujeres

BEGIN{ FS=":" } 
$3 ~ /F/ { print $0 }'

Update (Actualizar)

Hay varias maneras de actualizar un registro

  1. Añadir una columna
  2. Cambiar el valor de un registro basado en una condición
  3. Actualizar el valor de un grupo de registros basado en una condición

Adición de una columna

Queremos añadir al archivo la fecha de última modificación en formato ISO, sin parte temporal.

#!/bin/gawk
# PROGRAMA: crud-update.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-12
# PROPOSITO: Actualizar registros en awk añadiendo una columna

BEGIN {
    FS=":";
    OFS=":";
    date=strftime("%F", systime());
}
NR==1 { print $0,"LASTMOD" }
NR>1 { print $0,date }

Cambiar el valor de un sólo registro

Vamos a actualizar el nombre de Elle Parra con SSN 382-26-2505 a Elle Patterson, porque cambió su nombre al casarse. Tambien vamos a poner la fecha como última fecha de modificación como un campo al final y su fecha de cambio fue eo 2020-02-19.

#!/bin/gawk
# PROGRAMA: crud-update-one.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-13
# PROPOSITO: Actualizar registros en awk basados en una condicion

BEGIN { 
    FS=":"; 
    OFS=":";
    date="2020-02-19"; 
}
$5=="382-26-2505"{ $2="Patterson";$7=date }
{ print $0 }

Cambiar el valor de un grupo de registros

Para actualizar, vamos a usar de ejemplo las edades. Este dato está en la columna 4 y la fecha de nacimiento que es la columna 6

#!/bin/gawk
# PROGRAMA: crud-update-many.awk
# AUTOR: Otto Hahn Herrera
# FECHA: 2020-06-13
# PROPOSITO: Actualizar registros en awk basados en sus columnas

BEGIN { 
    FS=":"; 
    OFS=":";
    date="2020-06-12";
    split(date, d, /[- ]+/);
    dttime = mktime(d[1]" "d[2]" "d[3]" "00" "00" "00);
}

NR > 1{ split($6, t, /[- ]+/);
    dobt=mktime(t[1]" "t[2]" "t[3]" "00" "00" "00);
    yrst=(dttime-dobt)/31536000;
    $4=int(yrst);
    $7=date;
    print $0
}

Delete (borrar)

Para borrar, simplemente vamos a sobreescribir el archivo excluyendo los datos que cumplan la condición.

BEGIN{FS=":"; OFS=":"}
$5!="313-19-1866" { print $0 }'