SAS9

Comment sélectionner et lire le N-ième fichier d'un répertoire Unix avec SAS

Simon 12 views
Niveau de difficulté
Débutant
Published on :
Michael

Expert Advice

Michael

Ne faites jamais confiance à l'ordre 'naturel' retourné par le système d'exploitation via DREAD : il est souvent aléatoire (basé sur les inodes) et non alphabétique. L'étape de tri explicite (PROC SORT) de la liste des noms est l'unique garantie que votre '27ème fichier' sera toujours le même d'une exécution à l'autre

Il arrive souvent, lors de traitements de données sur serveur (notamment sous Unix), que l'on doive manipuler des fichiers sans connaître leur nom exact à l'avance, mais plutôt leur position dans une liste séquentielle.

Imaginez le scénario suivant : un répertoire contient une trentaine de fichiers CSV nommés de manière séquentielle (par exemple a.txt, b.txt, etc.). Votre objectif n'est pas de tout importer, mais de cibler spécifiquement le 27ème fichier de cette liste, quel que soit son nom, pour en traiter les données.

Voici une méthode robuste pour identifier, extraire et lire un fichier spécifique basé sur sa position, en utilisant les fonctions système de SAS©.

Comment sélectionner et lire le N-ième fichier d'un répertoire Unix avec SAS -

La stratégie en 3 étapes

Pour garantir que nous sélectionnons bien le 27ème fichier dans l'ordre alphabétique (ou séquentiel), nous ne pouvons pas nous fier au simple ordre de lecture du système d'exploitation, qui peut être aléatoire.

La procédure à suivre est la suivante :

  1. Lister le contenu du répertoire : Utiliser les fonctions de gestion de fichiers SAS© pour lire tous les noms de fichiers présents.

  2. Trier la liste : Ordonner les noms pour assurer la séquentialité (A vers Z).

  3. Extraire le fichier cible : Utiliser un accès direct (pointeur) pour récupérer le nom du fichier situé à la position N (ici, 27) et le stocker dans une macro-variable.

Implémentation technique

Étape 1 et 2 : Récupération et Tri

Nous allons d'abord créer une table SAS© (fnames) contenant la liste de tous les fichiers du dossier. Nous utilisons pour cela les fonctions DOPEN (pour ouvrir le dossier), DNUM (pour compter les fichiers) et DREAD (pour lire les noms).

Note importante : Il est crucial de lire tous les fichiers avant de trier. Si l'on s'arrête de lire au 27ème fichier trouvé par l

1DATA fnames;
2 LENGTH dref $8 fname $200;
3 /* 1. Assigner le répertoire à un fileref */
4 rc = filename(dref, "/chemins/vers/mon_dossier");
5
6 /* 2. Ouvrir le répertoire */
7 did = dopen(dref);
8
9 /* 3. Boucler sur tous les fichiers présents */
10 IF did THEN DO i = 1 to dnum(did);
11 fname = dread(did, i);
12 OUTPUT; /* Ajoute le nom à la table */
13 END;
14
15 /* Fermeture propre du répertoire */
16 rc = dclose(did);
17 keep fname;
18RUN;
19 
20/* 4. Trier les fichiers par nom pour garantir l'ordre séquentiel */
21PROC SORT DATA=fnames;
22 BY fname;
23RUN;

Étape 3 : Sélection directe avec l'option POINT=

Une fois la liste triée, nous n'avons pas besoin de lire toute la table. L'instruction SET avec l'option POINT= permet d'aller directement à la ligne souhaitée.

1DATA _null_;
2 /* Définir la position cible */
3 pt = 27;
4
5 /* Vérifier si le fichier existe (gestion d'erreur) */
6 IF pt > nobs THEN DO;
7 putlog "Erreur : Pas assez de fichiers dans le dossier.";
8 stop;
9 END;
10 
11 /* Accès direct à la 27ème observation */
12 SET fnames point=pt nobs=nobs;
13
14 /* Stocker le nom dans une macro-variable pour usage ultérieur */
15 call symputx('mon_fichier', fname);
16
17 /* Arrêter l'étape data immédiatement après la lecture */
18 stop;
19RUN;
20 
21/* Vérification dans la log */
22%put Le fichier sélectionné est : &mon_fichier;

Cette approche est universelle. Que vous cherchiez le 27ème ou le 100ème fichier, la logique reste la même. Une fois le nom du fichier stocké dans la macro-variable &mon_fichier, vous pouvez l'utiliser dynamiquement dans une procédure d'importation (comme PROC IMPORT) ou une étape Data classique pour lire le contenu du fichier.