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 date
y bash
(o cualquier shell que procese la sustitución con <(...)
) y que los datos se almacenen en el archivo file
como 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
cut
se utiliza junto contr
para transformar las fechas en las tres primeras columnas de los datos de entrada al formularioYYYY-MM-DD
. - Esto se pasa a GNU
date
para su procesamiento por lotes a través de su-f
opción. Como salida solicitamos fechas usando el formato%Y %j
.%Y
es el año en el formularioYYYY
y%j
es el día del año en el formularioDDD
. - 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ó.