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

Contribuez Discussion :

Trouver les fichiers contenant un texte CHAINE et afficher les lignes concernées [FAQ]


Sujet :

Contribuez

  1. #1
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut Trouver les fichiers contenant un texte CHAINE et afficher les lignes concernées
    En une ligne, on souhaite trouver dans quels fichiers se trouve la chaine CHAINE, lister leur chemin (relatif à notre position), et afficher les lignes contenant le fameux texte CHAINE.

    grep recursif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep -Rn "CHAINE" mon_repertoire/
    ou avec les couleurs, si votre grep et configuration le permettent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep --color -Rn "CHAINE" mon_repertoire/
    find + grep non récursif :
    Si on veut border la recherche avec des conditions plus strictes, par exemple, aux fichiers *.sh dont vous êtes l'utilisateur et qui sont executables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find depuis_ce_repertoire/ -type f -user moi_hornetbzz -perm /u+x -name "*.sh" -exec grep --color -Hn "CHAINE" {} 2>/dev/null \;
    ------------------- on pourrait s'arrêter là pour la FAQ, sinon pour l'arrachage de cheveux ----------
    Pour l'exercice, une version Debian/Ubuntu si vous avez les couleurs dans votre terminal :
    La combinaison de 3 commandes de base find, grep et sed va nous permettre cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DIR="mon_rep_de_recherche"; F_PATTERN="*"; CHAIN="ma_chaine_à_trouver"; COLOR=$'\033[1;33;40m'; \
    OFF=$'\E[0m'; find $DIR -type f -name "$F_PATTERN" -print0 | \
    while read -r -d "$(printf "\000")" -r path;\
    do [[ $(grep -r "$CHAIN" $path) ]] && ((count++)) && \
    echo -e "\nfile $count:  $path" && (grep -n "$CHAIN" $path | \
    sed -e "s/^\(.*\)/line \1/" -e 's/\('"$CHAIN"'\)/'"$COLOR"'\1'"$OFF"'/' ) ;\
    done
    Il y a très certainement une myriade d'autres solutions plus élégantes, en utilisant d'autres fonctions telles que awk/gawk ou bien en langage Perl. L'avantage de celle-ci réside dans l'utilisation de 3 commandes essentielles présentes dans toutes les distributions Linux, et dans la possibilité de sélectionner des fichiers particuliers (de type shell, et/ou avec les permissions executables et/ou appartenant à tel ou tel utilisateur etc...).

    [EDITED]
    Nota1: sed est utilisé dans son contexte "éditeur" et non "remplacement" de texte à proprement dit. Cette commande pourrait être omise.
    Nota2: la commande fonctionne en ligne de commande. Pour l'utiliser en Bourne Shell dans un script (#!/bin/sh) au lieu de Bash (#!/bin/bash) , il faudrait modifier ((count++)) par count=$((count+1)).
    Nota3: pour les développeurs qui utilisent Eclipse, cette commande est l'équivalent d'un search string. L'application évidente est la vérification ponctuelle de code sur un serveur en production.

  2. #2
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Salut,

    Je trouve la solution un peu lourde et tortueuse, alors qu'un simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find $DIR -type f -name "*" -exec sed -i.bak 's/XXX/YYY/' {} 2>/dev/null \;
    devrait suffire à mon avis... excepté pour la portabilité de l'option "-i.bak"
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  3. #3
    Expert éminent sénior Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Points : 12 264
    Points
    12 264
    Par défaut
    une solution non portable... c'est pas terrible...

  4. #4
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    [Mode avis personnel]
    Trop spécifique pour être vraiment pratique, et trop difficilement adaptable.
    L'exercice est intéressant sur le plan pratique, mais franchement, je n'utiliserais jamais ce genre de commande
    [/Mode avis personnel]

  5. #5
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Salut,

    Je trouve la solution un peu lourde et tortueuse, alors qu'un simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find $DIR -type f -name "*" -exec sed -i.bak 's/XXX/YYY/' {} 2>/dev/null \;
    devrait suffire à mon avis... excepté pour la portabilité de l'option "-i.bak"
    Attention: Remplacer "en aveugle" XX par YY n'est pas la vocation de la ligne de commande que je propose. Trop dangereux à mon sens et probablement pas adapté dans une FAQ où un copier/coller dans sa console peut vite conduire à la catastrophe.

    Ma proposition édite le path des fichiers et les lignes concernées par la recherche de texte. Volontairement sans risque. Essayes-la :-)
    A charge de l'utilisateur ensuite d'opérer un remplacement ou non selon son besoin. Alors il utilisera un sed de remplacement appliqué sur tel ou tel fichier. Ou une autre combinaison de commandes.

    Maintenant, il est certainement possible d'obtenir le même résultat autrement, je ne demande qu'à voir.

  6. #6
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    Citation Envoyé par Alek-C Voir le message
    [Mode avis personnel]
    Trop spécifique pour être vraiment pratique, et trop difficilement adaptable.
    L'exercice est intéressant sur le plan pratique, mais franchement, je n'utiliserais jamais ce genre de commande
    [/Mode avis personnel]
    Il n'y a rien à adapter.

  7. #7
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Citation Envoyé par hornetbzz Voir le message
    Attention: Remplacer "en aveugle" XX par YY n'est pas la vocation de la ligne de commande que je propose. Trop dangereux à mon sens et probablement pas adapté dans une FAQ où un copier/coller dans sa console peut vite conduire à la catastrophe.

    Maintenant, il est certainement possible d'obtenir le même résultat autrement, je ne demande qu'à voir.
    Ok, alors quid de (mise à part l'absence de coloration) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find $DIR -type f -name "*" -exec grep -Hn "${CHAIN}" {} 2>/dev/null \;
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  8. #8
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    Oui ça fonctionne aussi mais cette commande est loin de réaliser toute la fonctionnalité.

  9. #9
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Citation Envoyé par hornetbzz Voir le message
    Il n'y a rien à adapter.
    j'ai dit que c'était un avis personnel : si je ne veux pas "ligne :" mais "[ligne]", si je ne veux pas de couleur, si les couleurs ne passent pas sur mon terminal, si...

    en ce qui me concerne, ce n'est pas une commande que j'essaierais de retenir : elle est trop complexe et je n'en vois pas l'intérêt d'une manière générale

    De plus, j'ai fait un test pour voir ce que ça sortait comme résultat et ça n'a pas marché :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ DIR="."; F_PATTERN="*"; CHAIN="EZE"; COLOR=$'\033[1;33;40m'; OFF=$'\E[0m'; find $DIR -type f -name "$F_PATTERN" -print0 | while read -r -d "$(printf "\000")" -r path; do [[ $(grep -r "$CHAIN" $path) ]] && ((count++)) && echo -e "\nfile $count:  $path" && (grep -n "$CHAIN" $path | sed -e "s/^\(.*\)/line \1/" -e 's/\('"$CHAIN"'\)/'"$COLOR"'\1'"$OFF"'/' ) ; done
    $ grep -Rn EZE *
    t2/test.txt:3:dfgdfgd EZE elmfkdjlmfk
    La première commande ne renvoie rien, pourtant, je pense avoir correctement configuré les 3 variables (le find seul fonctionne en tout cas) ?

    Pour le fun, j'ai mis les couleurs que grep retourne tout seul comme un grand sur mon serveur (gentoo).

    Sur une machine Unix (HP-UX) sous ksh, la commande plante également :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ DIR="."; F_PATTERN="*"; CHAIN="EZE"; COLOR=$'\033[1;33;40m'; OFF=$'\E[0m'; find $DIR -type f -name "$F_PATTERN" -print0 | while read -r -d "$(printf "\000")" -r path; do [[ $(grep -r "$CHAIN" $path) ]] && ((count++)) && echo -e "\nfile $count:  $path" && (grep -n "$CHAIN" $path | sed -e "s/^\(.*\)/line \1/" -e 's/\('"$CHAIN"'\)/'"$COLOR"'\1'"$OFF"'/' ) ; done
    ksh: syntax error: `]]' unexpected
    En bref, sur un linux récent, j'ai grep qui fait ce que je crois avoir compris que ta commande faisait, et sur une machine plus ancienne, je pense qu'elle ne marchera pas !

    Mais encore une fois, c'est un avis personnel, et cela n'empêche pas que je trouve la commande très intéressante sur un plan pédagogique : je vais essayer de retenir la méthode utilisée (couplage de print0, de read, ...) qui pourra me servir un jour, mais pas au point d'en faire une commande générique !

  10. #10
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut
    ok pour le grep -Rn, 100% d'accord, c'est clairement plus portable pour quasiment le même résultat. Je modifie en conséquence.

  11. #11
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Citation Envoyé par hornetbzz Voir le message
    Oui ça fonctionne aussi mais cette commande est loin de réaliser toute la fonctionnalité.
    C'est vrai il manque le compteur

    Pour la couleur, rajouter "--color" à grep (pour les versions qui l'accepte) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find $DIR -type f -name "*" -exec grep --color -Hn "${CHAIN}" {} 2>/dev/null \;
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  12. #12
    Membre éclairé
    Avatar de hornetbzz
    Homme Profil pro
    Directeur commercial
    Inscrit en
    Octobre 2009
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Directeur commercial

    Informations forums :
    Inscription : Octobre 2009
    Messages : 482
    Points : 773
    Points
    773
    Par défaut


    Merci.

    J'ai édité la proposition initiale (c'est vrai, un tantinet "tortueuse" mais c'était zoli comme (une) Eclipse ) pour tenir compte de vos remarques et distinguer les deux cas d'utilisation de grep (recursif en soi ou recursivité obtenue par la combinaison avec find).

  13. #13
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    Une nouvelle Q/R a été rajoutée à la FAQ sur la base de la proposition d'hornetbzz : Comment trouver les fichiers contenant une chaîne de caractères et afficher les lignes concernées ?



    Idriss

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Afficher les fichiers contenant un terme
    Par cpalperou dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 04/10/2012, 14h23
  2. Trouver les fichiers contenant des annotations
    Par lahitsitely78 dans le forum Eclipse Platform
    Réponses: 0
    Dernier message: 18/02/2009, 12h52
  3. commande find: trouver les fichiers qui contiennent une chaine de caractère
    Par hammag dans le forum Administration système
    Réponses: 3
    Dernier message: 18/05/2008, 14h19
  4. Trouver les fichiers contenant un mot avec FINDSTR
    Par soazig dans le forum Windows XP
    Réponses: 4
    Dernier message: 26/04/2007, 15h29
  5. Trouver un fichier contenant une chaine ?
    Par narmataru dans le forum Linux
    Réponses: 2
    Dernier message: 29/04/2004, 11h49

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