Ver Mensaje Individual
  #2 (permalink)  
Antiguo 22/01/2015, 08:02
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Hacer JOIN de dos ficheros mediante Shell Script/AWK

Bueno, no has puesto los requisitos ordenados, pero creo que se entiende:
"Si un registro del fichero1 termina con S, y existe una línea en fichero2 que comience con los caracteres (x, x+n) del registro, sustituir en él dichos caracteres por los caracteres (n, hasta fin de línea) de la línea del fichero2".

Sería bastante más fácil si los campos estuviesen delimitados por espacios, en vez de caracteres. Para separar campos por caracteres se usa 'cut'. Se me ocurre esta forma, que no está mal si el archivo no es gigante:

Código BASH:
Ver original
  1. cp fichero1.dat fichero1.dat.original
  2. while read linea; do
  3.     # obtenemos los pares (clave, valor) del fichero2
  4.     K=$(echo $linea | cut -c1-4)
  5.     V=$(echo $linea | cut -c5-)
  6.     sed -i 's/^\(.*\)'$K'\(.*\)S$/\1'$V'\2S/g' fichero1.dat # sustituimos todas las líneas de fichero1 que contengan la clave y terminen en S
  7. done < fichero2.dat

El problema de esta solución es que lee y escribe fichero1 por cada línea de fichero2, con lo que si hablamos de decenas de miles de líneas, los tiempos de lectura+escritura del archivo pueden terminar siendo significativos.

Existe la posibilidad de leer todos los pares clave-valor de una vez, y luego hacer la sustitución línea por línea vía AWK, ya que awk soporta matrices asociativas. Otros lenguajes de programación, como Perl o Python, son una mejor opción si el programa tiene que hacer cosas más complejas.

Volviendo al tema de los campos delimitados por espacios, si tus archivos fuesen así:
Código BASH:
Ver original
  1. 25742telefono1 mac1 577S
  2. 64523telefono2 mac2 655N
  3.  
  4. mac1 valor15
  5. mac2 valor28
El comando join bastaría para resolver el problema (excepto, claro, por el asunto de que termine en S...):

# unir las líneas por el 2do campo del fichero1, y el 1er campo del fichero2, luego imprimir el primer campo del primer fichero, el segundo del segundo fichero, y el tercer campo del primer fichero.
Código BASH:
Ver original
  1. $ join -1 2 -2 1 -o 1.1 2.2 1.3 fichero1.dat fichero2.dat
  2. 25742telefono1 valor15 577S
  3. 64523telefono2 valor28 655N