2017-09-28 5 views
-1

J'ai besoin d'un fichier batch qui cherche un texte (par exemple, FOO) et le remplace par un autre texte (par exemple, BAR) dans tous les fichiers texte dans un dossier et ses sous-dossiers.Script Batch - Trouver et remplacer du texte dans plusieurs fichiers dans un répertoire sans demander à l'utilisateur d'installer un programme ou d'ajouter d'autres fichiers à mon script batch

Je dois donner ce fichier batch à l'utilisateur. Donc, il n'est pas possible de demander à l'utilisateur d'installer autre chose et je ne veux pas ajouter d'autres fichiers à mon script batch, est-ce que c'est passable? J'ai trouvé beaucoup de réponses à ce problème, mais tout le monde conseille d'installer un autre programme ou d'ajouter un fichier au script batch. Quelqu'un pourrait m'aider avec ça?

+0

[Cette réponse] (https://stackoverflow.com/q/60034) et [celui-ci] (https://stackoverflow.com/q/42052039) montrer comment remplacer le texte, en utilisant également natif de Windows les fonctions; essayez d'implémenter votre solution préférée dans une boucle pour gérer tous les fichiers correspondants dans une arborescence de répertoires ... – aschipfl

Répondre

2

Voici une solution pure et simple - Appelons replac.bat:

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

rem // Define constants here: 
set "_ROOT=%~3" & rem // (path to root directory; third command line argument) 
set "_MASK=%~4" & rem // (file search pattern; fourth command line argument) 
set "_SEARCH=%~1" & rem // (search string; first command line argument) 
set "_REPLAC=%~2" & rem // (replace string; second command line argument) 
set "_CASE=#"  & rem // (clear for case-insensitive search) 
set "_RECURS=#" & rem // (clear for non-recursive search) 
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path to temporary file) 

rem // Validate passed command line arguments, apply defaults: 
if not defined _SEARCH exit /B 1 
if not defined _ROOT set "_ROOT=." 
if not defined _MASK set "_MASK=*.txt" 

rem // Prepare `if` option (case-insensitivity) for later use: 
if defined _CASE (set "IFSW=") else (set "IFSW=/I") 
rem // Prepare `for` option (recursion) for later use: 
if defined _RECURS (set "FOROPT=/R") else (set "FOROPT=") 
rem // Change into root directory temporarily: 
pushd "%_ROOT%" || exit /B 1 
rem // Loop through all matching files in the directory tree: 
for %FOROPT% %%F in ("%_MASK%") do (
    rem // Write to temporary file: 
    > "%_TMPF%" (
     rem /* Read current file line by line; use `findstr` to precede every line by 
     rem its line number and a colon `:`; this way empty lines appear non-empty 
     rem to `for /F`, which avoids them to be ignored; otherwise empty lines 
     rem became lost: */ 
     for /F "delims=" %%L in ('findstr /N "^" "%%~fF"') do (
      rem // Store current line text: 
      set "LINE=%%L" & set "FLAG=" 
      setlocal EnableDelayedExpansion 
      rem // Remove line number prefix: 
      set "LINE=!LINE:*:=!" 
      rem // Skip replacement for empty line text: 
      if defined LINE (
       rem /* Use `for /F` loop to avoid trouble in case search or replace 
       rem strings contain quotation marks `"`: */ 
       for /F "tokens=1* delims== eol==" %%I in ("!_SEARCH!=!_REPLAC!") do (
        rem // Query to handle case-sensitivity: 
        if %IFSW% "!LINE!"=="!LINE:%%I=%%I!" (
         rem // Detect whether replacement changes line: 
         if not "!LINE!"=="!LINE:%%I=%%J!" (
          rem // Actually do the sub-string replacement: 
          set "LINE=!LINE:%%I=%%J!" 
          set "FLAG=#" 
         ) 
        ) 
       ) 
      ) 
      rem // Output the resulting line text: 
      echo(!LINE! 
      if defined FLAG (endlocal & set "FLAG=#") else (endlocal) 
     ) 
    ) 
    rem // Check whether file content would change upon replacement: 
    if defined FLAG (
     rem // Move the temporary file onto the original one: 
     > nul move /Y "%_TMPF%" "%%~fF" 
    ) else (
     rem // Simply delete temporary file: 
     del "%_TMPF%" 
    ) 
) 
popd 

endlocal 
exit /B 

Pour utiliser ce script, fournissez la chaîne de recherche en tant que première chaîne et la chaîne de remplacement en tant que deuxième argument de ligne de commande, respectivement; le troisième argument définit le répertoire racine qui par défaut dans le répertoire de travail en cours, et la quatrième définit le modèle de fichier qui est par défaut *.txt:

replac.bat "Foo" "Bar" 

Les restrictions suivantes:

  • tous les fichiers correspondant doit être des fichiers texte ASCII/ANSI avec des sauts de ligne de type Windows;
  • ni les lignes dans les fichiers ni les chaînes de recherche et de remplacement peuvent être plus long qu'environ 8190 octets/caractères;
  • la chaîne de recherche ne doit pas être vide, elle ne doit pas commencer par * ou ~ et ne doit pas contenir =;
  • la chaîne de remplacement ne doit pas commencer par =;
  • les chaînes de recherche et de remplacement ne doivent pas contenir !;
+0

@david et enfin, ne parlez pas à tout le monde au travail que vous avez écrit ce script :) –

1
for /r %i in (bar.txt) do echo ren "%i" foobar.txt 

Retirez le echo seulement une fois que vous êtes sûr que les fichiers vont être renommés correctement.

pour l'utiliser dans un fichier batch, ajouter % supplémentaire aux variables, comme:

@echo off 
for /r %%i in (bar.txt) do echo ren "%%i" foobar.txt 
+0

ce qui devrait être au lieu de "i"? – David

+0

'%% i' est la variable, elle ne devrait pas changer. Nous mettrons à jour la réponse pour l'expliquer. –

+0

Je veux changer le texte lui-même (dans le fichier .txt) et pas le nom du fichier:/ – David