GNU/Linux >> Tutoriels Linux >  >> Ubuntu

Pour une boucle avec des noms de fichiers ?

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 .


Ubuntu
  1. Le didacticiel de commande Shuf avec des exemples pour les débutants

  2. Chiffrement et déchiffrement de fichiers avec ccrypt

  3. Linux + Comment ignorer (filtrer) un fichier avec de l'espace ?

  4. Rechercher des fichiers avec Gui ?

  5. Comment grep pour le contenu après le modèle?

Bash For Loop avec des exemples pratiques

Le didacticiel de la commande mktemp avec des exemples pour les débutants

Le didacticiel de la commande Grep avec des exemples pour les débutants

Bash Scripting - Boucle For expliquée avec des exemples

Bash For Loops avec des exemples

Script bash pour la boucle expliqué avec des exemples