IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Quel langage (de script?) pratique pour parcourir/rechercher dans l'arborescence des fichiers/dossiers


Sujet :

Windows

  1. #1
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut Quel langage (de script?) pratique pour parcourir/rechercher dans l'arborescence des fichiers/dossiers
    Bonjour, (attention, double post : j'ai posé la même question dans le forum Langages de programmation, car je me demande si ce n'est pas plutôt une question sur les langages de programmation en générale. Si un admin souhaite supprimer l'une des deux, merci de plutôt supprimer celle-ci ..)

    Quel langage est selon vous pratique pour, sous Windows, faire des programmes du genre :
    • trouver tous les fichiers dont la taille est supérieure à X Mo, et s'arrêter quand on en a trouvé 321
    • trouver tous les dossiers qui contiennent un sous-dossier dont le nom est terminé par un nombre, nombre qui est divisible par 3
    • ...


    En gros, un langage qui permet de traiter l'arborescence des fichiers/dossiers comme un SGBD
    mais qui permette aussi d'écrire des clauses sur les noms/tailles/.. de dossiers et fichiers assez variées, plus du type programmation impérative (d'où m'on exemple sur les dossiers qui contiennent un sous-dossier dont le nom est terminé par un nombre et qui est divisible par 3).

    Et si vous pensez qu'il existe un Shell sous linux qui réponde mieux à ces exigences, pourquoi pas le signaler ! De toute façon, je suppose qu'avec Cygwin il sera possible de l'utiliser aussi sous Windows.

    Dans ma question, il y a également l'idée, je pense, que pour faire des recherches élaborées de fichiers/dossiers, il est utile de pouvoir écrire une fonction récursive qui parcourt donc récursivement les dossiers, et pour chaque, teste une clause écrite dans un langage impératif. Dans ce cas, on s'éloigne carrément du SGBD, on est plus dans la programmation impérative où le programme est basé sur une fonction récursive de parcourt d'arbre ?

    J'aimerais connaître votre avis, Merci !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Soit cygwin soit C++/ Boost


    Code sûrement sale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include<cstdlib>
    
    #include<iostream>
    #include<vector>
    
    #include<boost/filesystem.hpp>
    #include<boost/filesystem/operations.hpp>
    
    using namespace std;
    using namespace boost::filesystem;
    
    
    void test_path(path p, unsigned short maxdepth) {
        if ( exists(p) ) {
            if ( is_regular_file(p) ) {
                cout << p << " size is " << file_size(p) << '\n';
            } else if ( is_directory(p) ) {
                cout << p << " is a directory\n";
    
                if (maxdepth == 0) { return; }
    
                for (directory_iterator it(p); it != directory_iterator(); ++it) {
                    test_path((*it), (maxdepth- 1));
                }
            } else {
                cout << p << " exists, but is neither a regular file nor a directory\n";
            }
        } else {
            cout << p << " does not exist\n";
        }
    }
    
    
    int list_all_directories(path p, vector<string>& list) {
        list.empty();
    
        unsigned short nb_directories = 0;
    
        if ( exists(p) ) {
            if ( is_regular_file(p) ) {
                cout << p << " size is " << file_size(p) << '\n';
            } else if ( is_directory(p) ) {
                cout << p << " is a directory\n";
    
                for (directory_iterator it(p); it != directory_iterator(); ++it) {
                    if (exists( (*it) ) && is_directory( (*it) )) {
                        list.push_back( it->path().string() );
                        nb_directories++;
                    }
                }
            } else {
                cout << p << " exists, but is neither a regular file nor a directory\n";
            }
        } else {
            cout << p << " does not exist\n";
        }
    
        return nb_directories;
    }
    
    
    int main(int argc, char* argv[]) {
        if (argc < 2) {
            cout << "Usage: " << ((argc == 1)? argv[0]: "") << " str_path\n";
    
            return EXIT_FAILURE;
        }
    
        path p(argv[1]);
    
    //  test_path(p, 2);
    
        vector<string> list;
        unsigned short nb_directories = list_all_directories(p, list);
    
    //  Stuff here
    
        return EXIT_SUCCESS;
    }
    Édit: Le seul problème que je vois avec le C++ ce sont les chaînes de caractères, surtout s'il y a de l'Unicode, même si il y a std::string, petits frères et autres.

  3. #3
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    Oui ! Moi pour trouver tous les fichiers de taille supérieure à 1Go, j'ai fait la même chose en C/C++, directement avec la lib Win32 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    #include <windows.h>
    #include <string>
    #include <vector>
    #include <stack>
    #include <iostream>
    
    using namespace std;
    
    bool TraiterFichier(WIN32_FIND_DATA ffd, wstring path) {
    	double ngo = (ffd.nFileSizeHigh * MAXDWORD + ffd.nFileSizeLow) / ((double)(2 << 29));
    	if (ngo > 1) {
    		wcout << path << "\\" << ffd.cFileName << "    " << ngo << "Go" << endl;
    		return true;
    	}
    	return false;
    }
    
    typedef bool(*FuncTraiterFichier)(WIN32_FIND_DATA ffd, wstring path);
    
    void ListFiles(wstring path, wstring mask, vector<wstring>& files, FuncTraiterFichier funcTraiterFichier) {
    	HANDLE hFind = INVALID_HANDLE_VALUE;
    	WIN32_FIND_DATA ffd;
    	wstring spec;
    	stack<wstring> directories;
    
    	directories.push(path);
    	files.clear();
    
    	while (!directories.empty()) {
    		path = directories.top();
    
    		spec = path + L"\\" + mask;
    		directories.pop();
    		
    		hFind = FindFirstFile(spec.c_str(), &ffd);
    		if (hFind == INVALID_HANDLE_VALUE)  {
    			//return false;
    			continue;
    		}
    
    		do {
    			if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0) {
    				
    				//wcout << path+ ffd.cFileName << "\n";
    
    				if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    					wstring tmp = path + L"\\" + ffd.cFileName;
    					//directories.push(tmp);
    
    					ListFiles(tmp, mask, files, funcTraiterFichier);
    				}
    				else {
    					if (funcTraiterFichier(ffd, path)) {
    						files.push_back(path + L"\\" + ffd.cFileName);
    					}
    					
    				}
    			}
    		} while (FindNextFile(hFind, &ffd) != 0);
    
    		FindClose(hFind);		
    	}
    }
    
    int main(int argc, char* argv[])
    {
    	vector<wstring> files;
    
    	ListFiles(L"C:\\", L"*", files, TraiterFichier);
    
    	// lister ici files si on veut
    
    	return 0;
    }
    le problème c'est ce que ce n'est pas un langage de script, et qu'on voudrait pouvoir n'écrire que (dans mon exemple) la fonction TraiterFichier puisque le reste du code est générique et ne sert qu'à parcourir les sous-dossiers d'un dossier parent.

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 452
    Points : 43 103
    Points
    43 103
    Par défaut
    et sinon pour du script Powershell ou VBS.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    et sinon pour du script Powershell ou VBS.
    Et pourquoi pas php avec par exemple scandir et preg_match

    Par contre, si j'ai bien compris, PHP n'aime pas l'Unicode

  6. #6
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    et sinon pour du script Powershell ou VBS.
    salut, merci pour tes propositions !
    et si tu maîtrises un peu les avantages de ces langages, ça serait gentil de donner des pistes sur pourquoi c'est plus pratique qu'écrire une fonction récursive en C/C++

  7. #7
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 452
    Points : 43 103
    Points
    43 103
    Par défaut
    Et pourquoi pas php avec par exemple scandir et preg_match
    Oui Foetus, mais il était demandé du script, donc perso j'entends par là l'équivalent de bash et outils systèmes.

    Acx01b, je n'ai pas donné d'exemples car je ne les pratique pas, mais je pense que vbs est assez facile d'accès (je fais un peut de vba qui est ressemblant)
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  8. #8
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    Avec PowerShell tes exemples sont relativement simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Get-ChildItem -Recurse <Directory> | 
    Where { $_.Length -gt 10MB } | 
    Select -First 10
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Get-ChildItem -Recurse -File <Directory> |
    Where { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -match '[0-9]+$' -and (([int]$matches[0]) % 3) -eq 0 } |
    Select Directory -Unique

  9. #9
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    Alors meziantou tu es expert en Powershell ! Merci beaucoup en tout cas.

    Je vais essayer de commenter un peu tes codes Powershell, d'après ce que j'en ai compris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // truc généraliste qui permet de faire des appels récursifs sur un "conteneur" qui le permet
    Get-ChildItem -Recurse    
    //  ici le conteneur sur lequel on va notre récursion c'est un dossier en particulier, on a probablement donné une valeur genre "C:\\" plus haut à Directory ? 
    <Directory> |    
    // la clause à appliquer à chaque élément du conteneur
    Where { $_.Length -gt 10MB } | 
    // en plus on peut dire qu'on souhaite s'arrêter au 10ème
    Select -First 10    
    // on est en SGBD, donc pas besoin de dire ce qu'on veut faire avec 
    //le résultat : on veut trouver des résultats, c'est le but de notre code
    

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // pareil que plus haut
    Get-ChildItem -Recurse -File <Directory> | 
    /// alors là ... ça coince un peu parce que je pense que la programmation impérative 
    //a son utilité ! et ici on n'a pas de programmation impérative, c'est plus du SGBD, 
    //donc on est parti dans les syntaxes de ouf !!! 
    Where { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -match '[0-9]+$' -and   (([int]$matches[0]) % 3) -eq 0 } 
    /// ça ne j'ai pas compris, je ne suis pas sûr que ton code meziantou applique la clause à un des sous-directory 
    //(on veut un dossier dont un des sous-dossiers a un nom du type que tu as mis au dessus)
    |   Select Directory -Unique

    Donc en gros à ce que je comprends, c'est l'exemple typique du langage de SGBD qui permet de faire des trucs assez élaborés dans le système de fichiers. Mais la question que je me pose quand même, c'est est-ce qu'on n'a pas besoin à un moment de pouvoir écrire un peu de code impératif, dans les clauses ou même la manière de récurser dans l'arborescence ? Donc est-ce que l'idéal c'est vraiment un langage de SGBD ? Par qu'en plus là clairement on n'a pas trop envie d'apprendre toute la syntaxe et les API qui permettent d'écrire une clause comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Where { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -match '[0-9]+$' -and   (([int]$matches[0]) % 3) -eq 0 }
    Non ? Vous en pensez quoi

  10. #10
    Membre averti

    Profil pro
    Étudiant
    Inscrit en
    Décembre 2004
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2004
    Messages : 499
    Points : 422
    Points
    422
    Par défaut
    Ah oui !
    Et C# avec LINQ je suis presque sûr qu'il permet de mélanger justement SGBD (de type OQL) et des clauses en programmation impérative.

    Par exemple :
    https://www.google.fr/search?q=search+file+C%23+LINQ

  11. #11
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    Avec PowerShell tu peux allier langage descriptif et impératif. Les exemples que j'ai donné précédemment pourrait être fait avec une boucle foreach et des if (mais cela est plus long). Je viens de voir que mon deuxième exemple ne répond pas exactement à ce que tu voulais. Mon code liste les dossiers contenant au moins un fichier finissant par un nombre divisible par 3.

    Je détaille un peu cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Where { [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -match '[0-9]+$' -and (([int]$matches[0]) % 3) -eq 0 }
    [System.IO.Path]::GetFileNameWithoutExtension($_.Name) : PowerShell permet d'utiliser le framework .NET simplement http://msdn.microsoft.com/fr-fr/libr...v=vs.110).aspx
    -match : filtre une chaine de caractère (ici le nom du fichier) avec une regex
    -and : combine 2 conditions avec l'opérateur AND
    $matches[0] : premier groupe qui match la regex (ici le nombre)
    [int]$matches[0] : converti le texte en nombre (pour effectuer le calcul) (pas sûr que ce soit obligatoire)
    n % 3 : n modulo 3

    Petit exemple de boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    foreach ($num in 1,2,3,4,5)
    {
      if ($num -eq 2) { 
        continue 
      }
        
      Write-Host $num
    }

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/10/2014, 17h27
  2. Réponses: 2
    Dernier message: 17/04/2014, 12h33
  3. Quel langage de script pour s'interfacer avec C++ ?
    Par dwarfman78 dans le forum Bibliothèques
    Réponses: 7
    Dernier message: 22/08/2008, 18h06
  4. Quel langage de programmation utiliser pour un MMOG?
    Par @v@lon dans le forum Développement 2D, 3D et Jeux
    Réponses: 18
    Dernier message: 17/03/2007, 12h31
  5. Quel langage de scripts choisir?
    Par mig73 dans le forum Linux
    Réponses: 5
    Dernier message: 03/05/2006, 16h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo