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

Messages postés
8
Date d'inscription
jeudi 20 mars 2003
Dernière intervention
16 février 2011
- - Dernière réponse : chotana
Messages postés
8
Date d'inscription
jeudi 20 mars 2003
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
Afficher la suite 

Votre réponse

10 réponses

Meilleure réponse
Messages postés
8
Date d'inscription
jeudi 20 mars 2003
Dernière intervention
16 février 2011
3
Merci
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

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 106 internautes ce mois-ci

Commenter la réponse de chotana
Messages postés
14289
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
14 décembre 2018
0
Merci
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
Commenter la réponse de BunoCS
Messages postés
8
Date d'inscription
jeudi 20 mars 2003
Dernière intervention
16 février 2011
0
Merci
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
Commenter la réponse de chotana
Messages postés
14289
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
14 décembre 2018
0
Merci
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
Commenter la réponse de BunoCS
Messages postés
14289
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
14 décembre 2018
0
Merci
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
Commenter la réponse de BunoCS
Messages postés
8
Date d'inscription
jeudi 20 mars 2003
Dernière intervention
16 février 2011
0
Merci
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 ....
Commenter la réponse de chotana
Messages postés
14289
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
14 décembre 2018
0
Merci
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
Commenter la réponse de BunoCS
Messages postés
14289
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
14 décembre 2018
0
Merci
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
Commenter la réponse de BunoCS
Messages postés
719
Date d'inscription
lundi 5 décembre 2005
Dernière intervention
8 janvier 2014
0
Merci
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;
}
Commenter la réponse de cs_AlexN
Messages postés
719
Date d'inscription
lundi 5 décembre 2005
Dernière intervention
8 janvier 2014
0
Merci
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;
}
Commenter la réponse de cs_AlexN

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.