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

Scripts/Batch Discussion :

Remplacer une ligne par une autre dans un fichier txt


Sujet :

Scripts/Batch

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 83
    Points : 60
    Points
    60
    Par défaut Remplacer une ligne par une autre dans un fichier txt
    Bonjour à tous,

    Après avoir interrogé mes amis et , je n'ai toujours pas la réponse.

    Je voudrais en fait créer un batch qui fasse 'rechercher/remplacer' avec en paramètre la phrase à remplacer, la phrase de remplacement et le fichier concerné.

    J'ai commencé simple avec ce que j'ai trouvé sur le net :

    Mon fichier1.txt contient :
    toto titi tata
    tutu toto tonton
    titi

    J'exécute le batch ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @echo off
    setLocal EnableDelayedExpansion
    
    for /f "tokens=* delims= " %%a in (fichier1.txt) do (
    set str=%%a
    set str=!str:toto=roro!
    set str=!str:titi=sisi!
    set str=!str:tata=titi!
    echo !str!>>fichier2test.txt
    )
    type fichier2test.txt>fichier1.txt
    del fichier2test.txt
    Et après exécution mon fichier1.txt contient :
    roro sisi mimi
    tutu roro tonton
    sisi

    Qu'est-ce que tu demandes de plus me direz-vous?
    Je suis sûre qu'il existe un moyen de le faire directement, sans passer par un fichier temporaire et/ou d'améliorer ce code car je ne m'y connais point trop en commandes.
    Auriez-vous une idée?

    Pour plus d'informations, mon but final est en fait de modifier le contenu d'une balise <clause> </clause> d'un fichier xml. Mais il ne m'est pas possible d'accéder à un parser xml alors je prefère gérer le truc comme un simple fichier.

    merci de votre aide ou d'avoir pris le temps de me lire seulement.

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    En Batch, tu ne peux pas "éditer" un fichier, tu ne peux que le transformer en un autre... Donc, difficile à mon avis (pour ne pas dire "impossible") de faire ça sans un fichier "résultat", qui viendra donc remplacer le fichier "original".

    Quant à améliorer la boucle de traitement... Tu peux, en effet, en utilisant FIND ou FINDSTR pour obtenir les numéros des lignes ayant ces chaînes à modifier, et ensuite ajouter un "skip" adéquat à ta boucle FOR.
    Toutefois, si ton fichier n'est pas très volumineux, tu perdras plus de temps à utiliser ces outils qu'à traiter chaque ligne inconditionnellement !
    Au pifomètre, je dirais que si ton XML pèse moins de 500 ko, ton code actuel sera proche de l'optimal...

    Tu peux toutefois tenter de mettre le remplacement en tant que sous-programme (cf. aide de "call :étiquette"), et de n'effectuer le remplacement QUE si "FIND" appliqué à la ligne en cours trouve quelque chose. Tu pourras éventuellement gagner le temps de substitution des variables d'environnement, qui peut être long.
    Je doute quand même que tu puisses gagner beaucoup de temps d'exécution...

    Par contre, tu peux améliorer sévèrement la fin en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    del fichier1.txt
    ren fichier2test.txt fichier1.txt
    Ce sera largement plus rapide qu'une recopie de fichier via TYPE.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 83
    Points : 60
    Points
    60
    Par défaut
    Merci pour ta réponse. Effectivement, plus je cherche et plus je me rends compte que ça n'est pas possible.
    Par ailleurs merci pour les améliorations de code que je vais directement appliquer.

    Comme je l'ai dit, mon but est de modifier un fichier xml. J'ai vu bout de code intéressant sur le sujet mais pour le moins incompréhensible à mon niveau. Notamment, je ne comprends pas bien le rôle de FINDSTR ici ajouté dans le for. Pour bien comprendre, voici la version light que I'm_Here a d'abord proposé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @echo off
    
    ::_Chemin + nom du fichier Xml
    Set fileXml=C:\dossier 3\file.xml
    
    for /f "tokens=3 delims=<>" %%i In (
      'type "%fileXml%"^|findstr /c:"<id>"') do (
          ren "%fileXml%" "%%i.xml")
    pause

    Ici, je suis déjà perdue : j'aimerais intégrer sa syntaxe for à mon code pour pouvoir trouver la balise et mon code remplacera le contenu de la balise.
    Je pense que l'association des deux codes répond à ma question mais comment faire?

    Peux-tu m'aider à voir la lumière ?

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Le problème, c'est que le code de I'm_Here n'est pas adapté à ton problème... Là, il propose d'effectuer des opérations sur certains fichiers XML contenant une certaine chaîne (d'où le findstr), ou extraire le contenu d'une balise XML donnée (et jeter le reste...) pour l'utiliser en BATCH.

    En aucun cas il ne modifie le contenu du fichier XML... Seulement son nom ! Toi, tu fais exactement le contraire : tu modifie le contenu, mais pas le nom !!
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par tinwul Voir le message
    Je suis sûre qu'il existe un moyen de le faire directement, sans passer par un fichier temporaire
    salut,

    comme a dit Mac LAK , un fichier temporaire ne fera pas de mal, sinon:

    tu peux faire ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @echo off
    setLocal EnableDelayedExpansion
    
    for /f "tokens=* delims= " %%a in (fichier1.txt) do (
    set str=%%a
    set str=!str:toto=roro!
    set str=!str:titi=sisi!
    set str=!str:tata=titi!
    echo !str!>>fichier2test.txt
    )
    move fichier2test.txt fichier1.txt
    ou si tu veux sans fichier temporaire tu peux faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @echo off
    
    for /f "tokens=1* delims=:" %%i in ('findstr -n "<clause>" fichier1.xml') do (
     (
      echo %%i
      echo ^^^<balise^^^> nouvelle balise ^^^</balise^^^>
      echo w
      echo e
     ) | edlin /b fichier1.xml >nul 2>nul
    )
    mais ça reste une solution extrême.

    à mon avis tu peux t'orienter vers Perl tu aurra lus de choix

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par I'm_HERE Voir le message
    mais ça reste une solution extrême.
    Extrême, tu peux le dire... EDLIN mets 30 secondes à se charger la première fois que je le lance sur une console pour ma part, comme la plupart de ces "vieux" outils d'ailleurs (me demande pas pourquoi, j'en sais rien).

    Ceci étant dit, ça peut être plus efficace qu'une substitution systématique, à tester je dirais... En admettant que l'OP n'aie pas le même genre de souci au chargement d'EDLIN que moi bien sûr.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Extrême, tu peux le dire... EDLIN mets 30 secondes à se charger la première fois que je le lance sur une console pour ma part, .
    oui c'est vrai mais ensuite ça devrai allé assez bien, mais ça reste comme j'ai dis une solution peu académique..

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 83
    Points : 60
    Points
    60
    Par défaut
    I'm_Here, si ça ne tenait qu'à moi j'utiliserai n'importe quel langage de programmation qui gère bien mieux les fichiers que batch, malheureusement, mon batch doit être utilisé par un programme qui ne sait exécuter que du batch
    Mac Lak, je pense avoir besoin de la fonction findstr ou find.
    Mon problème est plus complexe qu'un simple 'rechercher/remplacer' en fin de compte

    Voici ce que je voudrais faire en réalité :

    lancer le batch ainsi : nobatch.bat param1 param2param1 est un nom de fichier et param2 est un chiffre.

    Je travaille sur le fichier xml param1 où je dois à la fois récupérer des informations et en modifier d'autres. Mes repères pour savoir quoi récupérer et quoi modifier sont les balises :
    <OrderBy>ContenuARecupérer</OrderBy> et <Clause>ContenuAModifier</Clause>

    Un exemple de fichier en entrée :

    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
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <Mid>
      <Procedure>
        <QueryBuilder type="SELECT">
          <Table>Newsletter with (nolock)</Table>
          <OrderBy>iNewsletter</OrderBy>
          <Colonnes>
            <Colonne>iNewsletter, Nom, Frequence</Colonne>
          </Colonnes>
    <Clauses>
           <Clause><![CDATA[iNewsletter > MaxID]]></Clause>
          </Clauses>
        </QueryBuilder>
        <Output>C:\xml_exe\Newsletter.csv</Output>
      </Procedure>
    </Mid>
    C'est parti :

    - Je veux récupérer le contenu de la balise <OrderBy> cad ici 'iNewsletter' et le placer dans la variable VOrdBy
    - Trouver la balise <Clause> et remplacer son contenu par ![CDATA[VOrdBy > param2]]

    Seul param1 peut me dire sur quel fichier je vais travailler, c'est pourquoi VOrdBy peut changer à chaque fois.

    J'espère que je me suis bien exprimée, sinon n'hésitez pas!

    Ce petit code remplace très bien un mot entre deux balises <Clause>, mais dès que j'essaie de l'adapter à mon fichier xml, il bloque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for /f "tokens=2 delims=<>" %%i in ('findstr "<Clause>" fichier1.txt') do (
    for /f "tokens=* delims= " %%a in (fichier1.txt) do (
    set r=%%a
    set r=!r:%%i=ligne changee!
    echo !r!>>fichiertest.txt
    )
    )
    La tête du fichier fichier1.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <toti>la</toti>
    <Clause>vie</Clause>
    <tito>est belle</tito>
    <idd>n'est-elle</idd>
    <coco>pas?</coco>
    Et le fichier de sortie, fichiertest.txt (je copierai la cible dans la source plus tard) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <toti>la</toti>
    <Clause>ligne changee</Clause>
    <tito>est belle</tito>
    <idd>n'est-elle</idd>
    <coco>pas?</coco>

    Le problème est que ![CDATA[iNewsletter > MaxID]] n'est pas aussi simple qu'un seul mot, il comporte des caractères que batch n'aime pas

    Bon je vous montrerai bien le code adapté au xml mais je crois avoir trop parlé

    Ai-je bien expliqué mon problème ou n'est-ce pas clair? merci encore de m'aider

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 83
    Points : 60
    Points
    60
    Par défaut
    J'ai fini par trouver un code qui fonctionne à peu près néanmoins j'ai encore besoin de votre aide pour un petit détail :

    Il y a quelque chose dans mon code qui supprime les point d'exclamations or j'en ai besoin!

    Si vous voyez d'où ça peut venir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @echo off
    setLocal EnableDelayedExpansion
    
    
    for /f "tokens=3 delims=[]" %%i in ('findstr "<Clause>" %1.xml') do (
    
    for /f "tokens=* delims= " %%a in (%1.xml) do (
    set r=%%a
    set r=!r:%%i=nomID^>%2!
    echo !r!>>fichier2test.txt
    )
    
    )
    Je pense que le problème vient de la ligne en gras mais comme je ne l'ai pas vraiment comprise...

    C'est le dernier souci je pense. Merci à celui ou celle qui me permettra de finir ce code rapidement!

    T'inquiète ram_000 j'ai tout bien mis les balises code

  10. #10
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par tinwul Voir le message
    Il y a quelque chose dans mon code qui supprime les point d'exclamations or j'en ai besoin!
    salut,

    c'est tout à fait normal, puisque tu a activé l'expansion retardée : dans cette environnement le signe "!" n'est pas considéré comme un simple caractère mais un identifiant des variables étendues..

    Bon, tu peux en modifiant un peu le code utilisant la commande EDLIN faire à peu près ce que tu veux

Discussions similaires

  1. Insérer une ligne entre deux autres dans un fichier
    Par c1malabar dans le forum Langage
    Réponses: 8
    Dernier message: 25/05/2011, 19h44
  2. Remplacer un texte par un autre dans un fichier
    Par Fredo67 dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 08/04/2009, 16h04
  3. Réponses: 5
    Dernier message: 09/11/2007, 09h59
  4. comment remplacer un caractere par un autre dans un fichier txt
    Par uzumaki_naruto dans le forum Langage
    Réponses: 6
    Dernier message: 24/07/2006, 13h33
  5. Remplacer un mot par un autre dans un fichier
    Par vbcasimir dans le forum Linux
    Réponses: 8
    Dernier message: 25/04/2006, 12h08

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