Como Hacer Un Join en Awk

AWK es un lenguaje de programación muy poderoso para procesar archivos de texto separados con columnas. Una de las tareas básicas con datos columnares es unir los registros basados en algún tipo de llave (como en las bases de datos). Esta unión puede ser utlizando una o varias columnas como llave, además de que hay manera de simular inner joins o outer joins. Para esto vamos a usar un subconjunto del dataset de empleados:

emp.csv

EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
7839,KING,PRESIDENT,,11/17/1981,5000,,10
7698,BLAKE,MANAGER,7839,05/01/1981,2850,,30
7782,CLARK,MANAGER,7839,06/09/1981,2450,,10
7566,JONES,MANAGER,7839,04/02/1981,2975,,20
7788,SCOTT,ANALYST,7566,12/09/1982,3000,,20
7902,FORD,ANALYST,7566,12/03/1981,3000,,20
7369,SMITH,CLERK,7902,12/17/1980,800,,20
7499,ALLEN,SALESMAN,7698,02/20/1981,1600,300,30
7521,WARD,SALESMAN,7698,02/22/1981,1250,500,30
7654,MARTIN,SALESMAN,7698,09/28/1981,1250,1400,30
7844,TURNER,SALESMAN,7698,09/08/1981,1500,0,30
7876,ADAMS,CLERK,7788,01/12/1983,1100,,20
7900,JAMES,CLERK,7698,12/03/1981,950,,30
7934,MILLER,CLERK,7782,01/23/1982,1300,,10

Y los departamentos:

dept.csv

DEPTNO,DNAME,LOC
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON

Inner join

Vamos a unir la tabla emp con dept para obtener la siguiente información: Número de empleado, nombre, número de departamento y nombre del departamento En SQL esto se haría de la siguiente manera:

SELECT
  E.EMPNO,
  E.ENAME,
  E.DEPTNO,
  D.DNAME
FROM EMP E
INNER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;

Y en awk esto se hace con el siguiente script:

leftinnerjoin.awk

#!/bin/awk -f

BEGIN {FS=","; OFS =","}
NR==FNR {key[$1]=$2; next}
NR!=FNR {print $1,$2,$8,key[$8]}
END {}

Outer join

Para simular un outer join, vamos a usar 2 archivos diferentes:

file3.csv

val1,value
1,JOHN
2,TOMMY
3,ESME
4,ADA
5,ARTHUR
6,KARL

y

file4.csv

val1,counts
1,100
2,320
5,532

El script para simular el outer join va a procesar el archivo file4.csv, guardando val1 como llave y counts como valor. Posteriormente, va a tomar file3.csv y va a revisar que val1 no esté en el array. Si está va a imprimir value y counts. Si no está, entonces imprime value y 0.

leftouterjoin.awk

#!/bin/awk -f

BEGIN {FS=","; OFS =",";
}
NR==FNR {key[$1]=$2; next}
{ if (key[$1] != "") {
        print $2,key[$1]
  } else {
        print $2, 0}
}
END {}

Llamamos este programa con los siguientes argumentos

$ awk -f leftouterjoin.awk file4.csv file3.csv

Y el resultado es:

value,counts
JOHN,100
TOMMY,320
ESME,0
ADA,0
ARTHUR,532
KARL,0

Con esto podemos simular la operación de joins de SQL en awk.