comparar archivos en base a dos columnas y agregar campo

comparar archivos en base a dos columnas y agregar campo

Tengo archivos con fechas y horas en columnas en formato "AAAA MM DD HHMM" más una variable (temperatura) y quiero convertirlos al formato AAAA DDD (y mantener la hora y la temperatura como están). Se ven así pero la misma fecha aparece varias veces en el archivo:

1980 01 01 0100 3.3
1982 04 11 0400 2.2
1985 12 04 0700 1.7
1995 12 31 1000 2.2

He creado un archivo de índice (1980-2017) con la cantidad de días que se agregarán a cada fecha del primer archivo para obtener el día acumulado del año DDD (última columna). El primer año se ve así (1980 fue un año bisiesto):

1980 01 31  000
1980 02 29  031
1980 03 31  060
1980 04 30  090
1980 05 31  121
1980 06 30  152
1980 07 31  182
1980 08 31  213
1980 09 30  244
1980 10 31  274
1980 11 30  305
1980 12 31  335

Estoy tratando de comparar los dos archivos en función de las dos primeras columnas y, si coinciden, agregar la cuarta columna del archivo 2 a la tercera columna del archivo 1 y terminar con algo como esto:

1980 001 0100 3.3 
1982 101 0400 2.2 
1985 346 0700 1.7 
1995 365 1000 2.2

Logré comparar las dos columnas de los archivos y agregar las dos columnas con awk a continuación:

awk -F' ' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' junktemp matrix_sample | awk '{print $1, $3+$4}' 

pero así pierdo $4 y $5 (hora y temperatura). ¿Hay alguna manera de combinar las dos funciones awk y obtener $4 y $5 del archivo1 también en el resultado? Cualquier ayuda muy apreciada.

Respuesta1

Es difícil realizar la prueba ya que solo has proporcionado coincidencias potenciales para un solo año, pero

awk 'NR==FNR{c[$1$2]=$4; next} ($1$2 in c) {$3 = sprintf("%03d", $3 + c[$1$2])} {print $1, $3, $4, $5}' file2 file1
1980 001 0100 3.3
1982 11 0400 2.2
1985 04 0700 1.7
1995 31 1000 2.2

Respuesta2

Suponiendo GNU datey bash(o cualquier shell que procese la sustitución con <(...)) y que los datos se almacenen en el archivo filecomo en los primeros datos de ejemplo de la pregunta:

$ paste -d ' ' <( date -f <( cut -d ' ' -f1-3 file | tr ' ' '-' ) +"%Y %j" ) \
               <( cut -d ' ' -f4-5 file )
1980 001 0100 3.3
1982 101 0400 2.2
1985 338 0700 1.7
1995 365 1000 2.2
  • El primero cutse utiliza junto con trpara transformar las fechas en las tres primeras columnas de los datos de entrada al formulario YYYY-MM-DD.
  • Esto se pasa a GNU datepara su procesamiento por lotes a través de su -fopción. Como salida solicitamos fechas usando el formato %Y %j. %Yes el año en el formulario YYYYy %jes el día del año en el formulario DDD.
  • Esto se pega junto con las dos últimas columnas del archivo original (producido por el segundo cut) usando un solo espacio como delimitador.

Esta es una transformación directa de los datos originales al resultado final, evitando la necesidad del archivo de índice que creó.

información relacionada