Reemplazar columnas desde otro archivo – awk

Agradecimiento a  : https://inteligenciaux.wordpress.com/2010/09/21/reemplazar-columnas-desde-otro-archivo/

Supongamos que tenemos este archivo de datos llamado datafile:

20081010 1123 xxx
20081011 1234 def
20081012 0933 xyz
20081013 0512 abc
20081013 0717 def
...thousand of lines...

 

Donde “xxx”, “def”, etc. son codigos o abreviaturas. Queremos reemplazar cada codigo o abreviatura con su respectiva descripcion, que se encuentra en otro archivo llamado mapfile asi como este:

abc withdrawal
def payment
xyz deposit
xxx balance
...other codes...

Para reemplazar los codigos en el archivo de datos, se puede hacer con el siguiente comando:

# use information from a map file to modify a data file
awk 'NR==FNR{a[$1]=$2;next} {$3=a[$3]}1' mapfile datafile

El arreglo “a” indexado por el codigo, es llenado con la descripcion del archivo “mapfile” o el primer archivo que se le pase, luego este es usado durante la lectura del segundo archivo para hacer los reemplazos. Cada linea de “datafile” o del segundo archivo, es impreso despues de cada sustitucion.

Entendiendolo mejor:

Se lee el primer archivo linea a linea y va llenando el arreglo “a”, de tal forma que el indice del arreglo es el primer campo de cada linea del primer archivo  “mapfile”  y el contenido de esa posicion es el segundo campo de cada linea en el primer archivo “mapfile”

a[abc]=withdrawal
a[def]=payment
a[xyz]=deposit
a[xxx]=balance

Despues se empieza a leer el segundo archivo “datafile” linea a linea y se va reasignando la variable $3 de awk que en realidad es el campo 3 del segundo archivo, por el valor que contiene el arreglo segun el indice, por lo tanto en la pantalla se imprimira el contenido del segundo archivo “datafile” pero con el nuevo valor de la variable $3

 $3=a[xxx] <==> $3=balance

Solo queda el numero 1 que aparece despues de la lectura del segundo archivo:

{$3=a[$3]}1

Creo que lo que significa el “1” es que solo haga el reemplazo 1 sola vez, pero estoy especulando y estoy casi seguro que esta deduccion es incorrecta

El resultado final seria:

20081010 1123 balance
20081011 1234 payment
20081012 0933 deposit
20081013 0512 withdrawal
20081013 0717 payment
...thousand of lines...
Ejemplo con passwd y group

Teniendo el archivo passwd:

bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

Y el /etc/group:

bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
adm:x:4:root,adm,daemon
lp:x:7:daemon,lp

Si queremos reemplazar el id del grupo por el nombre en el archivo passwd, lo hacemos con el comando:

awk -F: 'NR==FNR{a[$3]=$1;next} {$4=a[$4]}1' 'OFS=:' /etc/group /etc/passwd > salida

Las opciones -F y OFS significan el separador que va a usar awk para leer y escribir los campos respectivamente; como estamos leyendo el passwd usamos el “:” y lo mismo para cuando el awk los va a escribir

Esto daria como resultado algo como:

bin:x:1:bin:bin:/bin:/sbin/nologin
daemon:x:2:daemon:daemon:/sbin:/sbin/nologin
adm:x:3:adm:adm:/var/adm:/sbin/nologin
lp:x:4:lp:lp:/var/spool/lpd:/sbin/nologin

Tomado de:

http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/

http://backreference.org/2010/02/10/idiomatic-awk/

http://www.marblestation.com/?p=761

http://www.unix.com/es/shell-programming-scripting/138665-comparing-2-files-awk-updating-2nd-file.html

http://www.gnu.org/manual/gawk/gawk.html

http://oreilly.com/catalog/unixnut3/chapter/ch11.html

http://kaneda.bohater.net/faq/awk1line.txt

http://www.softpanorama.org/Tools/awk.shtml#Read-Terminal

Deja un comentario