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

Shell et commandes GNU Discussion :

Find & replace sur un ensemble de fichiers


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 47
    Points : 45
    Points
    45
    Par défaut Find & replace sur un ensemble de fichiers
    Bonjour
    Sous windows je faisais ça avec dreamweaver : il donnait la possibilité de faire un "find & replace" en choisissant un dossier et il ouvrait tous les fichiers de ce dossier et remplaçait les chaînes de caractères concernées.

    Sous linux je ne vois pas trop comment faire. Quel logiciel le permet ? Sinon comment puis-je me faire un petit script shell pour ça ?

    Merci
    Totofweb

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 68
    Points : 71
    Points
    71
    Par défaut
    Il n'y a pas de logiciel appropriés, il faut faire un script en combinant la commande find et la commande sed.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e 's/$VAR1/$VAR2/g' fichier
    te permet de remplacer les occurences $VAR1 par $VAR2 dans tout le fichier....

  3. #3
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Bonsoir

    Voici un petit script qui devrait correrspondre à ce que tu cherche :
    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
     
    #! /bin/bash
     
    # Je génère une fichier temporaire et je récupère son nom
    TEMPFILE=$(tempfile)
     
    # Je récupère la liste des fichiers qui contiennent le motif $1 à partir du répertoire $3
    LISTFILE=$(grep -l -R $1 $3)
     
    # Je traite chacun des fichiers récupérés
    for f in $LISTFILE ; do
            # Je modifié le motif $1 par la chaine $2 et je redirige la sortie de sed dans le fichier temporaire
    	sed -e "s/$1/$2/g" $f > $TEMPFILE
            # Je fais une sauvegarde du fichier d'origine au cas ou :)
    	cp $f ${f}~
            # j'écrase l'ancien fichier par le nouveau
    	cp $TEMPFILE $f
    done
    # j'efface le fichier temporaire
    rm -f $TEMPFILE
    usage :
    (si ce script est copié dans un fichier replace.sh)
    ./replace "toto" "titi" /tmp/dir : remplace "toto" par "titi" dans tous les fichiers de /tmp/dir et ses sous répertoires
    ./replace "toto" "titi" /tmp/dir/*.html : ne remplace "toto" par "titi" que dans les fichier .html de /tmp/dir et pas dans les sous répertoire.



    et voilou

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 47
    Points : 45
    Points
    45
    Par défaut
    Ok merci pour le script.

    Je trouve quand même dommage d'avoir autant d'éditeurs mais pas un seul qui sache effectuer cette opération pourtant pas si compliquée mais fort utile.

  5. #5
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    mais qui a dit qu'ils ne savaient pas le faire ?
    Les éditeurs vi et xemacs, par exemple, sont très puissant et je suis sure qu'en cherchant un peu dans leur commandes on doit pouvoir y arriver mais un script est si simple (de plus tous les éditeurs permettent de lancer des commandes externes...)

  6. #6
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Points : 5 915
    Points
    5 915
    Par défaut
    Toujours en bash, mais plus court

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i in $( find ./ -type f  ) 
     do  
       sed -e s/EXPRESSION1/EXPRESSION2/g  $i > $i.bak
       mv $i.bak $i 
    done

  7. #7
    ovh
    ovh est déconnecté
    Rédacteur
    Avatar de ovh
    Homme Profil pro
    Architecte devops web full stack
    Inscrit en
    Mai 2002
    Messages
    3 841
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte devops web full stack

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 841
    Points : 6 514
    Points
    6 514
    Par défaut
    Encore plus court, à tester :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.cpp" | xargs sed -e s/regexp1/regexp2/
    (sert à remplacer qqch dans tous les fichiers cpp récurisvement à partir du répertoire courant)

    La commande xargs transmet chaque ligne de résultat de la première en commande en argument de la seconde commande 8)

  8. #8
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Points : 5 915
    Points
    5 915
    Par défaut
    Encore plus court ... mais qui ne fait pas la meme chose car il manque la modification des fichiers

  9. #9
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    le script que j'ai proposé n'est pas beaucoup plus long que les autres si on enlève les commentaires
    De plus si on enlève la sauvegarde du fichier d'origine et la suppression du fichier temporaire il n'y a plus aucune différence

    becket >> le .bak de ton script n'est pas la sauvegarde du fichier d'origine


  10. #10
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Voici la commande pour le faire sous un éditeur, au hasard vi :

    ouvrir vi :
    #vi
    Charger les fichiers dans les buffers (par exemple ouvrir tous les fichier .c et .h d'un répertoire) :
    :args /path1/path2/.../*.[ch]
    Effectuer une commande sur l'ensemble des buffers, par exemple la commande qui remplace 'toto' par 'titi' sur l'ensemble d'un fichier et même s'il y a plusieurs occurence par ligne, sans confirmation :
    :bufdo %s/toto/titi/g
    La même commande en enregistrant automatiquement les modifications et en confirmant les modifications :

    :bufdo %s/toto/titi/gc | update
    il est trop fort ce vi

  11. #11
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par narmataru
    le script que j'ai proposé n'est pas beaucoup plus long que les autres si on enlève les commentaires
    De plus si on enlève la sauvegarde du fichier d'origine et la suppression du fichier temporaire il n'y a plus aucune différence

    becket >> le .bak de ton script n'est pas la sauvegarde du fichier d'origine

    1 - Ton script est toujours plus long de deux petites lignes meme avec tout ce tu as enlevé

    2 - Pourquoi faire une copie de sauvegarde d'un fichier que l'on ne modifie pas ... On cree un nouveau fichier qui est modifié.

  12. #12
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Citation Envoyé par becket
    2 - Pourquoi faire une copie de sauvegarde d'un fichier que l'on ne modifie pas ... On cree un nouveau fichier qui est modifié.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            # Je fais une sauvegarde du fichier d'origine au cas ou :)
       cp $f ${f}~
            # j'écrase l'ancien fichier par le nouveau
       cp $TEMPFILE $f
    bien sure qu'il est modifié le fichier $f mais une sauvegarde est fait au préalable au cas ou on veut revenir en arrière

    Dans ton script $i et ${i}.bak ont les même donnée, non ?

  13. #13
    Expert confirmé
    Avatar de becket
    Profil pro
    Informaticien multitâches
    Inscrit en
    Février 2005
    Messages
    2 854
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Informaticien multitâches
    Secteur : Service public

    Informations forums :
    Inscription : Février 2005
    Messages : 2 854
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par becket
    Citation Envoyé par narmataru

    becket >> le .bak de ton script n'est pas la sauvegarde du fichier d'origine


    2 - Pourquoi faire une copie de sauvegarde d'un fichier que l'on ne modifie pas ... On cree un nouveau fichier qui est modifié.
    Je parlais de mon script :

    Citation Envoyé par becket
    sed -e s/EXPRESSION1/EXPRESSION2/g $i > $i.bak
    A ce moment, tu as deux fichiers : un $i.bak qui est le fichier modifié et un $i qui est le fichier non modifié

  14. #14
    Nouveau membre du Club
    Inscrit en
    Novembre 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 38
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par becket
    Toujours en bash, mais plus court

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i in $( find ./ -type f  ) 
     do  
       sed -e s/EXPRESSION1/EXPRESSION2/g  $i > $i.bak
       mv $i.bak $i 
    done
    salut !

    Et si on ne veut remplacer que le mot entier ?
    Par exemple remplacer tous les "normal" par "Normal" (donc pas dans "normalIndex" par exemple)

  15. #15
    Nouveau membre du Club
    Inscrit en
    Novembre 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 38
    Points : 27
    Points
    27
    Par défaut
    bon finalement j'ai trouvé, ct pas tres dur mais ca fais longtemps que j'ai pas touché à ca... j'ai donc utilisé "\ Expression\ " pour ne trouver que mon mot entier.
    A +

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

Discussions similaires

  1. Répéter une commande sur un ensemble de fichiers
    Par sohoney dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 11/01/2013, 10h55
  2. Réponses: 2
    Dernier message: 20/10/2011, 16h22
  3. [Batch] Exécuter une commande sur un ensemble de fichiers
    Par flo44 dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 23/04/2010, 16h07
  4. traitement sur un ensemble de fichiers selectionner
    Par captainamerica75 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 13/09/2007, 18h22
  5. Find and replace sur plusieur fichiers
    Par dazhoid dans le forum MATLAB
    Réponses: 1
    Dernier message: 30/08/2006, 16h18

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