J'ai plusieurs fichiers (tables) nommés :institut _
modèle _
scénario _
rivière .txt
(institut , modèle , scénario , et rivière sont des variables.) Je voudrais créer un for
boucle qui identifiera chaque fichier ayant le même institut nom et en même temps le même scénario nom, afin d'ajouter les résultats de chaque modèle différent dans le même fichier de sortie, à l'aide de la commande suivante :
paste filename1.txt filename2.txt > output_file.txt
Je sais comment créer un for
boucle sur un dossier différent mais pas sur les noms de fichiers. Quelqu'un a une idée ?
À titre d'exemple minimal, les noms de fichiers pourraient être les suivants :
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
Ensuite, je voudrais ajouter les fichiers suivants :
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
Réponse acceptée :
Si les fichiers sont tous dans le même répertoire, vous pouvez :
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
}'
qui divise le nom du fichier sur "_" (-F_
), fixe les variables i,m,s
aux 3 premières parties du nom de fichier (institut,modèle,scénario),
et accumule dans le tableau f le nom de fichier. Le tableau est indexé
uniquement par l'institut et le scénario, donc tous les modèles sont concaténés
(m n'est pas utilisé). Le dernier END imprime le tableau f et utilise l'index (institute_scenario) comme
nom pour le fichier de sortie. Avec vos exemples, cela produit
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
Vous devez ensuite le diriger dans le shell pour qu'il soit exécuté. Ajouter | sh
à la dernière ligne ci-dessus pour le faire.
Pour supprimer certaines colonnes des fichiers d'entrée, vous devez modifier la ligne awk
qui collecte tous les noms de fichiers d'entrée. Dans la 1ère ligne awk :
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
le nom du fichier est le "$0". Par exemple, si vous remplacez cette ligne par :
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] sprintf(" <(cut -f4 %s)",$0) }
alors vous obtiendrez l'exemple de sortie :
paste <(cut -f4 wbm_gfdl_rcp8p5_mississippi.txt) <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
mais si vous voulez couper uniquement le 2ème nom de fichier, c'est un peu plus compliqué et
vous avez besoin de ceci à la place :
{ 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 }
ainsi vous obtiendrez
paste wbm_gfdl_rcp8p5_mississippi.txt <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
Si sh
ne comprend pas la syntaxe <(cut ...)
puis remplacez-le par bash
.