Récupérer en C++ le résultat d'une commande

Résolu
chotana Messages postés 8 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 février 2011 - 15 sept. 2006 à 13:41
chotana Messages postés 8 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 février 2011 - 19 sept. 2006 à 12:17
Salut,


je cherche

1- à parcourir tous les sous répertoire à partir d'un répertoire de départ

2- rechercher tous les fichiers .config

3- pour chaque fichier l'ouvrir et regarder s'il y a le mot clé TRUC

4- si le mot clé est présent alors afficher le chemin+nom du fichier

5- récupérer la liste des fichiers en C++


voici mon souci : en shell je fais

for i in `find . -name .config` ;do

    if cat $i |grep TRUC ;

    then echo $i;

    fi  ;

done


Ca marche, j'obtient 2 lignes pour chaque fichier :

1- une ligne qui contient le mot clé

2- une ligne qui contient le chemin+nom du fichier


Mon pb est d'exécuter cette commande en C++ et de récupérer le résultat dans un tableau


Qui peut m'aider ?


Merci

10 réponses

chotana Messages postés 8 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 février 2011
19 sept. 2006 à 12:17
voila ce que j'ai finalement fait, et ça a l'air de marcher ; bon ok, c'est certainement pas optimisé


        FILE *f;

        char buf[256];

        string str_buf, str_sousChaine;

  

    const char * chemin = "/rep1/rep2/";

        char * commande ="for i in `find ";

   

    strcat(commande, chemin);

    strcat(commande," -name .truc` ;do if cat $i |grep MOT_CLE ");

    strcat(commande, "  > /dev/null; then echo $i; fi  ; done");


        f=popen(commande,"r");

   

        while (fgets(buf, sizeof buf, f))

        {

                str_buf=buf;

               
// si on trouve .truc dans la ligne, alors traiter cette ligne

                int pos=str_buf.find(".truc");

        if (pos!=-1) {

                       
size_t size = str_buf.size() + 1;

                       
char * buffer = new char[ size ];

                       
strncpy( buffer, str_buf.c_str(), size-2 );

                       


                       
// Ouverture du fichier en lecture

                       
std::ifstream fichier(buffer);

           

                       
if ( fichier ) // ce test échoue si le fichier n'est pas ouvert

                       
{

                       
    std::string ligne; // variable contenant chaque
ligne lue


                            
    // cette boucle s'arrête dès qu'une erreur de
lecture survient

                            
    while ( std::getline( fichier, ligne ) )

                            
    {

           
        //lecture et traitment des lignes
une à une

                    size = ligne.size() + 1;

           
        char * buf_ligne = new char[ size
];

           
        strncpy( buf_ligne,
ligne.c_str(), size );

                   

                    // afficher la ligne à l'écran

                   cout<<ligne<<endl;

                            
}

                       
} else {

                       
cout << "erreur ouverture du fichier :
"<<fichier<<endl ;

                       
}

                }

        }


        pclose(f);

}


voilou
3
BunoCS Messages postés 15358 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 mars 2023 102
15 sept. 2006 à 14:38
Je ne suis pas sûr de moi, à vérifier et à tester donc, mais je crois que:
- tu mets ton code dans un fichier bat
- pour lancer le bat, tu utilise CreateProcess() (voir MSDN)
- cette fonction prend en paramètre une structure STARTUPINFO dans laquelle tu spécifie les différentes sorties (entrée, sortie, erreur)
- une fois que le process est fini (et c'est là que je ne suis pas certain), tu dois avoir moyen de récupérer la sortie, dans laquelle s'est affiché ton résultat, et tu peux la parser.

Sinon, et c'est ce que je te conseille, tu peux utiliser l'API Windows: FindFirstFile(), FindNextFile() pour parcourir un répertoire. Après, manipulation classique de fichiers.

En espérant d'avoir aidé

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
0
chotana Messages postés 8 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 février 2011
15 sept. 2006 à 14:42
oulah !


ca m'a l'air bien compliqué tout ça ; je pense qu'avec popen je pourrais arriver à récupérer le flux, mais je ne vois pas très bien comment.


Au fait, je travaille sous Linux, pas sous Windows
0
BunoCS Messages postés 15358 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 mars 2023 102
15 sept. 2006 à 14:53
M'en serais douté
Désolé mais mon aide s'arrête là...
Ceci dit, tu peux transcrire ton code shell en C++

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BunoCS Messages postés 15358 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 mars 2023 102
15 sept. 2006 à 14:55
Ah oui, désolé! Je n'avais pas lu l'endroit où tu avais posté ([infomsg.aspx Thèmes] / [infomsgf_CPLUSPLUS-CPLUSPLUS-NET_3.aspx C++ & C++ .NET] / [infomsgt_LINUX_366.aspx Linux] /...)
Au temps pour moi...

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
0
chotana Messages postés 8 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 février 2011
15 sept. 2006 à 14:57
de rien, mais ça n'arrange pas mes affaires


j'aurais voulou éviter de faire tout ça en C++ d'autant que le shell le fait très bien en une ligne de commande ....
0
BunoCS Messages postés 15358 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 mars 2023 102
15 sept. 2006 à 15:00
Je viens de faire une recherche sur le site et j'ai trouvé ceci:
http://www.cppfrance.com/infomsg_EXECUTER-COMMANDE_802853.aspx
ça peut peut-être t'aider, non?

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
0
BunoCS Messages postés 15358 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 23 mars 2023 102
15 sept. 2006 à 15:01
Avec le lien:
http://www.cppfrance.com/infomsg_EXECUTER-COMMANDE_802853.aspx

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 18
16 sept. 2006 à 02:32
Chez moi ça n'affiche rien...
Si tu oublies l'option -print de find, find n'affichera pas de résultat
find . -name .config -print
l'instruction if n'accepte de tester que des expressions entières, et grep renvoie des chaines de caractères.

for i in `ls -a *.config`; do
    if [[ `grep TRUC $i | wc -l` -ne 0 ]];
    then echo $i;
    fi;
done

version c :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

void usage (char *argv[]) {
    printf ("Usage : %s MotAChercher RepertoireDeRecherche ExtensionDeFichier\n", *argv);
    exit (EXIT_SUCCESS);
}
void erreur (char *err, char *f) {
    char msg[100];
    sprintf (msg, "%s %s", err, f);
    perror(msg);
    exit (EXIT_FAILURE);
}

int main(int argc, char *argv[]) {

    FILE *f;
    DIR *dir;
    struct dirent *d;
    char *ext, *mot, *buf;
    char p[PATH_MAX+1+256+1];
    size_t t;
   
    if ( argc != 4 ) usage(argv);
    if ( !(ext = (char *) malloc (strlen(argv[3]) + 1)) ) { perror("malloc"); exit (EXIT_FAILURE); }
    strcpy (ext, argv[3]);
    if ( !(mot = (char *) malloc (strlen(argv[1]) + 1)) ) { perror("malloc"); exit (EXIT_FAILURE); }
    strcpy (mot, argv[1]);
    // Ouvrir le repertoire
    if ( !(dir = opendir(argv[2])) ) erreur ("Problème pour ouvrir le répertoire", argv[2]);
        // Parcourir les entrées du repertoire
        while ( (d = readdir(dir)) )
            if ( strstr(d->d_name, ext) ) {
                // Contruire le chemin du fichier
                strcpy (p, argv[2]);
                if ( *argv[2]+strlen(argv[2]) != '/' ) strcat (p, "/");
                strcat (p, *(d->d_name) == '/' ? d->d_name+1 : d->d_name);
                // Ouvrir le fichier en lecture
                if ( !(f = fopen (p, "r")) ) erreur("Problème pour ouvrir en lecture le fichier", d->d_name);   
                if ( fseek(f, 0L, SEEK_END) == -1 ) { perror("fseek"); exit (EXIT_FAILURE); }                if ( (t ftell(f)) -1 ) { erreur("Fichier trop gros :", d->d_name); exit (EXIT_FAILURE); }
                rewind(f);
                // Chercher le mot
                if ( !(buf = (char *) malloc (t)) ) { perror("malloc"); exit (EXIT_FAILURE); }
                if ( !fread (buf, t, 1, f) )  { perror("fread"); exit (EXIT_FAILURE); }
                if ( strstr(buf, mot) ) { puts(p); }
                if ( fclose(f) == EOF ) erreur("Problème pour fermer le fichier", d->d_name);
            }
    if ( closedir(dir) == -1 ) erreur ("Problème pour fermer le répertoire", argv[2]);
    return EXIT_SUCCESS;
}
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 18
16 sept. 2006 à 03:43
Il manquait une ligne :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

void usage (char *argv[]) {
    printf ("Usage : %s MotAChercher RepertoireDeRecherche ExtensionDeFichier\n", *argv);
    exit (EXIT_SUCCESS);
}
void erreur (char *err, char *f) {
    char msg[100];
    sprintf (msg, "%s %s", err, f);
    perror(msg);
    exit (EXIT_FAILURE);
}

int main(int argc, char *argv[]) {

    FILE *f;
    DIR *dir;
    struct dirent *d;
    char *ext, *mot, *buf;
    char p[PATH_MAX+1+256+1];
    size_t t;
   
    if ( argc != 4 ) usage(argv);
    if ( !(ext = (char *) malloc (strlen(argv[3]) + 1)) ) { perror("malloc"); exit (EXIT_FAILURE); }
    strcpy (ext, argv[3]);
    if ( !(mot = (char *) malloc (strlen(argv[1]) + 1)) ) { perror("malloc"); exit (EXIT_FAILURE); }
    strcpy (mot, argv[1]);
    // Ouvrir le repertoire
    if ( !(dir = opendir(argv[2])) ) erreur ("Problème pour ouvrir le répertoire", argv[2]);
        // Parcourir les entrées du repertoire
        while ( (d = readdir(dir)) )
            if ( strstr(d->d_name, ext) ) {
                // Contruire le chemin du fichier
                strcpy (p, argv[2]);
                if ( *argv[2]+strlen(argv[2]) != '/' ) strcat (p, "/");
                strcat (p, *(d->d_name) == '/' ? d->d_name+1 : d->d_name);
                // Ouvrir le fichier en lecture
                if ( !(f = fopen (p, "r")) ) erreur("Problème pour ouvrir en lecture le fichier", d->d_name);   
                if ( fseek(f, 0L, SEEK_END) == -1 ) { perror("fseek"); exit (EXIT_FAILURE); }                if ( (t ftell(f)) -1 ) { erreur("Fichier trop gros :", d->d_name); exit (EXIT_FAILURE); }
                rewind(f);
                // Chercher le mot
                if ( !(buf = (char *) malloc (t)) ) { perror("malloc"); exit (EXIT_FAILURE); }
                if ( !fread (buf, t, 1, f) )  { perror("fread"); exit (EXIT_FAILURE); }
                if ( strstr(buf, mot) ) { puts(p); }
                if ( fclose(f) == EOF ) erreur("Problème pour fermer le fichier", d->d_name);
                free(buf);
            }
    if ( closedir(dir) == -1 ) erreur ("Problème pour fermer le répertoire", argv[2]);
    return EXIT_SUCCESS;
}
0
Rejoignez-nous