Tengo varios archivos (tablas) llamados como:instituto _
modelo _
escenario _
río .txt
(instituto , modelo , escenario y río son variables). Me gustaría crear un for
bucle que identificará cada archivo que tenga el mismo instituto nombre y al mismo tiempo el mismo escenario nombre, para agregar los resultados de cada modelo diferente en el mismo archivo de salida, usando el siguiente comando:
paste filename1.txt filename2.txt > output_file.txt
Sé cómo crear un for
bucle sobre carpeta diferente pero no sobre nombres de archivo. ¿Alguien tiene una idea?
Como ejemplo mínimo, los nombres de archivo podrían ser los siguientes:
wbm_gfdl_rcp8p5_mississippi.txt
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_miroc_rcp8p5_mississippi.txt
Luego, me gustaría agregar los siguientes archivos juntos:
wbm_gfdl_rcp8p5_mississippi.txt with
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt with
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt with
matsiro_miroc_rcp8p5_mississippi.txt
Respuesta aceptada:
Si todos los archivos están en el mismo directorio, puede:
ls |
awk -F_ '{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
END{ for(insc in f)
printf "paste%s >out_%s.txt\n",f[insc],insc
}'
que divide el nombre del archivo en “_” (-F_
), establece las variables i,m,s
en las primeras 3 partes del nombre del archivo (instituto, modelo, escenario),
y acumula en la matriz f el nombre del archivo. La matriz está indexada
solo por el instituto y el escenario, por lo que todos los modelos están concatenados
(no se usa m). El END final imprime la matriz f y usa el índice (institute_scenario) como el nombre
para el archivo de salida. Con tus ejemplos esto produce
paste wbm_gfdl_rcp8p5_mississippi.txt wbm_hadgem_rcp8p5_mississippi.txt >out_wbm_rcp8p5.txt
paste matsiro_hadgem_rcp4p5_mississippi.txt matsiro_ipsl_rcp4p5_mississippi.txt >out_matsiro_rcp4p5.txt
paste matsiro_gfdl_rcp8p5_mississippi.txt matsiro_miroc_rcp8p5_mississippi.txt >out_matsiro_rcp8p5.txt
Luego debe canalizar esto en el shell para que se ejecute. Añadir | sh
a la última línea de arriba para hacer esto.
Para eliminar algunas columnas de los archivos de entrada, debe modificar la línea awk
que recopila todos los nombres de archivo de entrada. En la primera línea awk:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
el nombre del archivo es “$0”. Por ejemplo, si cambia esta línea a:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] sprintf(" <(cut -f4 %s)",$0) }
entonces obtendrá la salida de ejemplo:
paste <(cut -f4 wbm_gfdl_rcp8p5_mississippi.txt) <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
pero si desea cortar solo el segundo nombre de archivo, es un poco más complicado y
necesita esto en su lugar:
{ i=$1; m=$2; s=$3;
if(f[i"_"s]=="")add = $0; else add = sprintf("<(cut -f4 %s)",$0);
f[i"_"s] = f[i"_"s] " " add }
así obtendrás
paste wbm_gfdl_rcp8p5_mississippi.txt <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
Si sh
no entiende la sintaxis <(cut ...)
luego reemplácelo por bash
.