79 votes

Comment remplacer des sous-chaînes dans un fichier batch Windows

Quelqu'un peut-il me dire comment, à l'aide d'un fichier batch sous Windows, lire un fichier et remplacer une chaîne de caractères par une autre ? bath à partir du fichier contenant= bath Abath Bbath XYZbathABC avec la chaîne hello pour que la sortie soit comme hello Ahello Bhello XYZhelloABC

107voto

aflat Points 2543

L'expansion de Andriy M et oui, vous pouvez le faire à partir d'un fichier, même s'il comporte plusieurs lignes.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "OUTTEXTFILE=test_out.txt"
set "SEARCHTEXT=bath"
set "REPLACETEXT=hello"

for /f "delims=" %%A in ('type "%INTEXTFILE%"') do (
    set "string=%%A"
    set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
    echo !modified!>>"%OUTTEXTFILE%"
)

del "%INTEXTFILE%"
rename "%OUTTEXTFILE%" "%INTEXTFILE%"
endlocal

EDITAR

Merci David Nelson, j'ai mis à jour le script pour qu'il n'ait plus les valeurs codées en dur.

1 votes

C'est joli et ça marche, mais il enlève les lignes vides pour une raison quelconque. La réponse de Gonzalezea au lien suivant résout le problème de suppression des lignes vides : stackoverflow.com/a/20227248/280109

1 votes

Quelques informations pour les lecteurs qui envisagent d'utiliser le code : POUR ignore les lignes vides et, avec ce code, également les lignes commençant par ; parce qu'elle est la valeur par défaut de l'option eol . Lignes avec un ou plusieurs ! ne sont pas traitées correctement avec ce code en raison de l'expansion retardée activée requise par ce code. ECHO sorties echo is off. en cas de variable d'environnement modified est supprimée car la chaîne de remplacement est une chaîne vide et la chaîne de recherche correspond à la ligne entière. La chaîne de recherche ne peut pas contenir un signe égal à cause de = a une signification particulière dans l'expression de substitution.

0 votes

Ce code est-il très différent si j'ai besoin de modifier deux chaînes de caractères distinctes, par exemple en utilisant une autre chaîne de caractères set "modified1=... ?

50voto

Andriy M Points 40395
SET string=bath Abath Bbath XYZbathABC
SET modified=%string:bath=hello%
ECHO %string%
ECHO %modified%

EDITAR

Je n'ai pas vu au début que vous vouliez que le remplacement soit précédé par la lecture de la chaîne de caractères depuis un fichier.

Avec un fichier batch, vous n'avez pas beaucoup de possibilités de travailler sur des fichiers. Dans ce cas particulier, il faut lire une ligne, effectuer le remplacement, puis sortir la ligne modifiée, et ensuite... Et ensuite ? Si vous devez remplacer toutes les occurrences de 'bath' dans tout le fichier, vous devrez utiliser une boucle :

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
FOR /F %%L IN (file.txt) DO (
  SET "line=%%L"
  SETLOCAL ENABLEDELAYEDEXPANSION
  ECHO !line:bath=hello!
  ENDLOCAL
)
ENDLOCAL

Vous pouvez ajouter une redirection à un fichier :

  ECHO !line:bath=hello!>>file2.txt

Ou vous pouvez appliquer la redirection au fichier batch. Il debe être un fichier différent.

EDIT 2

Ajout d'un basculement approprié de l'expansion retardée pour le traitement correct de certains caractères qui ont une signification spéciale avec la syntaxe du lot script, comme ! , ^ et al. (Merci, jeb !)

0 votes

OK, donc au moins pour une chaîne de caractères, c'est possible avec les fonctions batch de Windows (non compatible avec DOS batch ou les anciennes versions de Windows). Mais je serais surpris que cela fonctionne sur un fichier (surtout un fichier avec plusieurs lignes).

1 votes

@schnaader : C'est possible, jetez un coup d'oeil à Recherche et remplacement par lots

0 votes

@jeb : OK, donc c'est possible au moins, merci pour le lien. De toute façon, les deux "très compliqué" et "incompatible" de ma réponse s'appliquent ici.

12voto

gonzalezea Points 164

Pour éviter de sauter les lignes vides (pour donner de la lisibilité au fichier de conf) je combine aflat et jeb answer ( aquí ) à quelque chose comme ça :

@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"findstr /n ^^ %INTEXTFILE%"') do (
   SET string=%%A
   for /f "delims=: tokens=1,*" %%a in ("!string!") do set "string=%%b"
   if  "!string!" == "" (
       echo.>>%OUTTEXTFILE%
   ) else (
      SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
      echo !modified! >> %OUTTEXTFILE%
  )
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%

0 votes

Vous pouvez également définir la page de code correcte, afin d'éviter les problèmes avec les caractères non-ansi dans le fichier texte : ex. chcp 65001 pour UTF8 : voir Écho des caractères UTF-8 dans les lots Windows

4voto

eichhorn Points 40

Pour éviter les problèmes liés à l'analyseur syntaxique des lots (point d'exclamation, par exemple), consultez le site suivant Problème avec le fichier batch de recherche et de remplacement .

Suite à la modification de aflat Le script de l'utilisateur comprendra des caractères spéciaux comme des points d'exclamation.

@echo off
setlocal DisableDelayedExpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"type %INTEXTFILE%"') do (
    SET string=%%A
    setlocal EnableDelayedExpansion
    SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!

    >> %OUTTEXTFILE% echo(!modified!
    endlocal
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%

-2voto

schnaader Points 26212

Vous ne devriez pas utiliser les fichiers batch pour modifier des chaînes de caractères ou même des fichiers, vous vous retrouverez soit avec une très Un fichier batch compliqué, un fichier batch légèrement incompatible (les fonctions les plus utiles des fichiers batch sont pour Windows NT et plus) ou l'utilisation de programmes externes pour effectuer la recherche/remplacement pour vous. Il suffit de lancer votre langage de script/programmation préféré et de l'appeler à partir du fichier batch.

Je ne dis donc pas que ce n'est pas possible du tout, mais vous vous éviterez des ennuis en ne l'essayant pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X