J'ai plusieurs fichiers (tables) nommés comme: institute_
modèle_
scénario_
- rivière.txt
(institut, modèle, scénario, et rivière sont des variables.) J'aimerais créer un for
boucle qui identifiera chaque fichier ayant le même nom institute et en même temps le même scénario nom, afin d’ajouter les résultats de chaque fichier différent model 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 une boucle for
sur différents dossiers, mais pas sur les noms de fichiers. Quelqu'un a une idée?
Comme 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, j'aimerais annexer 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
Si les fichiers se trouvent 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 de fichier en "_" (-F_
), définit les variables i, m, s sur les 3 premières parties du nom de fichier (institute, 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, de sorte que tous les modèles sont concaténés (m n'est pas utilisé). La dernière END affiche le tableau f et utilise l'index (institute_scenario) comme nom du 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 diriger cela dans le shell pour l'exécuter. Ajoutez | 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 de fichier est le "$ 0". Par exemple, si vous modifiez cette ligne en:
{ 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 en avez besoin à 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 }
alors vous aurez
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 ...)
, remplacez-la par bash
.
Tout d'abord, il n'y a pas de différence entre une boucle for
pour les répertoires et une boucle pour les fichiers. C'est exactement la même chose. Rappelez-vous que sur * nix, tout est un fichier .
Donc, votre boucle ressemblerait à ceci:
for institute in institute1 institute2 institute3
do
for scenario in scenario1 scenario2 scenario3
do
paste "$institute"_*_"$scenario"* > "$institute"_"$scenario".out
done
done
Si vous ne connaissez pas les noms d'institut et de scénario, vous pouvez simplement l'exécuter pour tous les fichiers et les extraire des noms de fichiers (tant que vos noms ne contiennent pas d'espaces):
for f in *; do echo "${f/_*} ${f##*_}"; done |
sort -u | while read ins sce; do
paste "$ins"_*_"$sce"* > "$ins"_"$sce".out
done
Peut-être en utilisant la commande ls. Quelque chose comme ls $institute_*_$scenario_*.txt
devrait renvoyer tous les fichiers avec le même institut et le même scénario.