Comment rechercher et remplacer du texte dans un fichier à l'aide de l'environnement de ligne de commande Windows?

492

J'écris un script de fichier batch en utilisant l'environnement de ligne de commande Windows et je veux changer chaque occurrence d'un texte dans un fichier (ex. "FOO") par une autre (ex. "BAR"). Quelle est la manière la plus simple de procéder? Des fonctions intégrées?

Rayon
la source

Réponses:

308

Beaucoup de réponses ici m'ont aidé à me diriger dans la bonne direction, mais aucune ne me convenait, donc je poste ma solution.

J'ai Windows 7, qui est livré avec PowerShell intégré. Voici le script que j'ai utilisé pour trouver / remplacer toutes les instances de texte dans un fichier:

powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"

Pour l'expliquer:

  • powershell démarre powershell.exe, qui est inclus dans Windows 7
  • -Command "... " est un argument de ligne de commande pour powershell.exe contenant la commande à exécuter
  • (gc myFile.txt)lit le contenu de myFile.txt( gcest l'abréviation de la Get-Contentcommande)
  • -replace 'foo', 'bar'exécute simplement la commande replace pour remplacer fooparbar
  • | Out-File myFile.txt redirige la sortie vers le fichier myFile.txt
  • -encoding ASCII empêche la transcription du fichier de sortie en unicode, comme le soulignent les commentaires

Powershell.exe devrait déjà faire partie de votre instruction PATH, mais sinon, vous pouvez l'ajouter. L'emplacement de celui-ci sur ma machine estC:\WINDOWS\system32\WindowsPowerShell\v1.0

Rachel
la source
71
Attention, cette commande peut également transcoder le fichier en encodage Unicode. Vous pouvez spécifier manuellement l'encodage en ajoutant -encoding ASCIIou UTF8ou tout ce qui est nécessaire. Attention également, si vous ciblez UTF8, il peut introduire une marque d'ordre d'octet au début du fichier qui n'apparaissait pas dans l'original.
Wyck
78
@Wyck Il m'a fallu un certain temps pour savoir où mettre -encoding ASCII. Pour quiconque en aurait besoin à l'avenir, ce seraitOut-File -encoding ASCII myFile.txt
rwilson04
15
La seule chose que je devais changer était d'utiliser Set-Contentau lieu de Out-File.
kurtzmarc
6
Cela fonctionne, mais les performances sont terribles, même sur une courte liste de fichiers.
jsuddsjr
23
Attention, le jeton de remplacement ('foo' dans ce cas) est traité comme une expression régulière. Si vous avez des caractères spéciaux (j'avais []), vous devez les ajouter au début avec un \ (barre oblique inverse).
JW
183

Si vous utilisez une version Windows qui prend en charge .Net 2.0, je remplacerais votre shell. PowerShell vous donne toute la puissance de .Net à partir de la ligne de commande. Il existe également de nombreux commandlets. L'exemple ci-dessous résoudra votre question. J'utilise les noms complets des commandes, il existe des alias plus courts, mais cela vous donne quelque chose pour Google.

(Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
Mike Schall
la source
10
Je peux voir que PowerShell est capable d'archiver cela. Mais comment puis-je effectuer cette exécution à partir d'un fichier de commandes (exemple: myProc.bat)?
Pablo Venturino
3
@Pablo, utilisez powershell.exe et enveloppez la commande ps en un seul paramètre
lubos hasko
56
-1 .. Bien sûr, la réponse a été acceptée, mais ce n'est pas la réponse à la question spécifiée.
baash05
28
Cela échouera avec une erreur de fichier en cours d'utilisation si vous enregistrez dans le même fichier. Vous devez modifier la commande powershell en: (Get-Content test.txt) | ForEach-Object {$ _ -replace "foo", "bar"} | Set-Content test.txt
BigMomma
6
Voir la réponse de @Rachel:powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | sc myFile.txt"
Nigel Touch
161

FART vient d'être utilisé ( utilitaire de ligne de commande " F ind A et R eplace T ext"):
excellent petit freeware pour le remplacement de texte dans un grand ensemble de fichiers.

Les fichiers d'installation se trouvent sur SourceForge .

Exemple d'utilisation:

fart.exe -p -r -c -- C:\tools\perl-5.8.9\* @@APP_DIR@@ C:\tools

affichera un aperçu des remplacements à faire récursivement dans les fichiers de cette distribution Perl.

Seul problème: l'icône du site FART n'est pas exactement de bon goût, raffinée ou élégante;)


Mise à jour 2017 (7 ans plus tard) jagb le souligne dans les commentaires de l'article 2011 " FARTing the Easy Way - Find And Replace Text " de Mikail Tunç

VonC
la source
19
Ce qui est cool, c'est que c'est un seul exe. Pas de dépendances. Pas de petits tirages. Super facile à déployer.
Serge Wautier
2
Très léger et facile à utiliser, mais j'espérais qu'il imprimerait les emplacements exacts des remplacements. Ne pas voir cela m'a donné un sentiment d'insécurité.
William Niu
4
Merci, c'est parfait, devrait faire partie des outils de dosage standard et fonctionner à merveille. L'option -p cependant ne vous montre pas combien de changements elle "apporterait" et rapporte toujours 0 qui m'a jeté pendant quelques minutes
sradforth
3
Je comprends que c'est une très vieille question, mais j'ai trouvé plus d'informations et j'espère que cela sera utile aux utilisateurs de Stack Overflow. Juste un autre lien pour FART où le produit est bien expliqué: FART a expliqué @ emtunc.org et une autre page peut être trouvée ici: FART S'il vous plaît soyez prudent avec le remplacement de /et 'comme cela ne fonctionne pas pour nous tous , pour moi, cela a fonctionné dans certains cas mais cela n'a pas fonctionné sur certains fichiers et je ne sais pas pourquoi .. J'ai utilisé cela pour remplacer du texte par un autre texte et un/
jagb
4
@jagb Merci. J'ai inclus votre lien dans la réponse pour plus de visibilité.
VonC
128

Remplacer - Remplacer une sous-chaîne à l'aide de la substitution de chaîne Description: pour remplacer une sous-chaîne par une autre chaîne, utilisez la fonction de substitution de chaîne. L'exemple présenté ici remplace toutes les occurrences "teh" des fautes d'orthographe par "the" dans la variable de chaîne str.

set str=teh cat in teh hat
echo.%str%
set str=%str:teh=the%
echo.%str%

Sortie de script:

teh cat in teh hat
the cat in the hat

ref: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

Bill Richardson
la source
30
Comment la suggestion sed est-elle meilleure? Cela semble être la réponse la plus simple de toutes et ne nécessite rien d'installation.
DonBecker
5
Peut-on faire une sorte de correspondance de motifs ici? Caractères génériques, regex, etc.?
Keyo
27
"Comment la suggestion sed est-elle meilleure?" - sed et des utilitaires similaires fonctionnent sur les fichiers; cet extrait de code omet l'étape importante de lecture des lignes du fichier d'entrée et d'écriture dans le fichier de sortie, tout en garantissant que tous les caractères spéciaux du fichier sont traités correctement.
Joe
7
@Asad, oui c'est vrai, l'OP posait des questions sur les fichiers, mais en fait cela fonctionne avec des flux qui ne doivent pas nécessairement être des fichiers. Mais mon point ici est que cette réponse est erronée, car elle omet la lecture / écriture d'un flux et la gestion des caractères spéciaux.
Joe
4
@Bill comment utiliser la variable comme texte de remplacement? c'est à dire. J'ai de la valeur dans une variable et une chaîne qui a un délimiteur. set str =% str: "##" =% varValue %% ne fonctionne pas. Des solutions?
MalTec
55

Créez le fichier replace.vbs:

Const ForReading = 1    
Const ForWriting = 2

strFileName = Wscript.Arguments(0)
strOldText = Wscript.Arguments(1)
strNewText = Wscript.Arguments(2)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
strText = objFile.ReadAll
objFile.Close

strNewText = Replace(strText, strOldText, strNewText)
Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
objFile.Write strNewText  'WriteLine adds extra CR/LF
objFile.Close

Pour utiliser ce script révisé (que nous appellerons replace.vbs), tapez simplement une commande similaire à celle-ci à partir de l'invite de commande:

cscript replace.vbs "C:\Scripts\Text.txt" "Jim " "James "

user459118
la source
c'est bien, cela permet-il d'utiliser RegEx?
user280109
3
@ user280109 Oui, VBScript prend en charge RegExp. Vous pouvez l' utiliser pour remplacer une expression régulière: With (New RegExp): strNewText = .Replace(strText, strOldText, strNewText): End With. Vous pouvez obtenir le texte des 9 premiers groupes de capture à l' aide $1, $2... $9.
Brosse à dents
2
VBScript est souvent négligé (et détesté), mais est disponible sur toutes les plates-formes Windows, est très lisible et possède en fait des capacités très puissantes +1
zelanix
1
@ user280109 Vous venez de donner la commande, Ce dont j'ai besoin. Mais je veux remplacer (insensible à la casse) Pouvez-vous fournir la commande pour cela?
Ajmal Praveen
49

BatchSubstitute.batsur dostips.com est un exemple de recherche et de remplacement à l'aide d'un fichier batch pur.

Il utilise une combinaison de FOR, FINDet CALL SET.

Les lignes contenant des caractères parmi "&<>]|^peuvent être traitées incorrectement.


morechilli
la source
8
Je dois remettre en question l'utilité d'un site d'extraits de code dont les conditions d'utilisation interdisent la copie du code («Vous ne pouvez pas diffuser les informations fournies sous le domaine dostips.com sous quelque forme que ce soit sans l'autorisation écrite expresse du propriétaire du domaine.») .
Gilles 'SO- arrête d'être méchant'
1
Je suis d'accord que leurs termes sont déroutants, ils disent également "Les informations fournies sous le domaine dostips.com sont, espérons-le, utiles", donc je suppose qu'ils sont heureux que les gens copient le code pour résoudre un problème. Je ne suis pas sûr d'avoir lu les termes et conditions et j'ai été heureux ...
morechilli
5
C'est bien. J'adore les réponses qui n'impliquent pas de télécharger autre chose pour le faire.
Ruairi O'Brien
J'aime aussi les solutions qui n'impliquent pas d'utilitaires externes, malheureusement, je reçois toujours "find: invalid predicate ''" lorsque j'essaie d'exécuter ce lot. Je n'ai pas vraiment le temps de le déboguer maintenant.
Jahmic
2
L'erreur "find: invalid predicate" "" était due à un utilitaire externe "find" sur mon système. Une fois retiré, cela a bien fonctionné.
Jahmic
47

Remarque - Assurez-vous de voir la mise à jour à la fin de cette réponse pour un lien vers le JREPL.BAT supérieur qui remplace REPL.BAT
JREPL.BAT 7.0 et supérieur prend en charge nativement unicode (UTF-16LE) via l' /UTFoption, ainsi que tout autre jeu de caractères, y compris UTF-8, via ADO !!!!


J'ai écrit un petit utilitaire hybride JScript / batch appelé REPL.BAT qui est très pratique pour modifier des fichiers ASCII (ou ASCII étendu) via la ligne de commande ou un fichier batch. Le script purement natif ne nécessite l'installation d'aucun exécutable tiers et il fonctionne sur toute version Windows moderne à partir de XP. Il est également très rapide, en particulier par rapport aux solutions par lots pures.

REPL.BAT lit simplement stdin, effectue une recherche et un remplacement d'expression régulière JScript et écrit le résultat dans stdout.

Voici un exemple trivial de la façon de remplacer foo par bar dans test.txt, en supposant que REPL.BAT se trouve dans votre dossier actuel, ou mieux encore, quelque part dans votre PATH:

type test.txt|repl "foo" "bar" >test.txt.new
move /y test.txt.new test.txt

Les capacités d'expression régulière JScript le rendent très puissant, en particulier la capacité du texte de remplacement à référencer les sous-chaînes capturées à partir du texte de recherche.

J'ai inclus un certain nombre d'options dans l'utilitaire qui le rendent assez puissant. Par exemple, la combinaison des options Met Xpermet la modification des fichiers binaires! L' Moption multiligne permet des recherches sur plusieurs lignes. L' Xoption de modèle de substitution eXtended fournit des séquences d'échappement qui permettent l'inclusion de toute valeur binaire dans le texte de remplacement.

L'utilitaire entier aurait pu être écrit en JScript pur, mais le fichier batch hybride élimine la nécessité de spécifier explicitement CSCRIPT chaque fois que vous souhaitez utiliser l'utilitaire.

Voici le script REPL.BAT. La documentation complète est intégrée au script.

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::************ Documentation ***********
::REPL.BAT version 6.2
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?[REGEX|REPLACE]
:::REPL  /V
:::
:::  Performs a global regular expression search and replace operation on
:::  each line of input from stdin and prints the result to stdout.
:::
:::  Each parameter may be optionally enclosed by double quotes. The double
:::  quotes are not considered part of the argument. The quotes are required
:::  if the parameter contains a batch token delimiter like space, tab, comma,
:::  semicolon. The quotes should also be used if the argument contains a
:::  batch special character like &, |, etc. so that the special character
:::  does not need to be escaped with ^.
:::
:::  If called with a single argument of /?, then prints help documentation
:::  to stdout. If a single argument of /?REGEX, then opens up Microsoft's
:::  JScript regular expression documentation within your browser. If a single
:::  argument of /?REPLACE, then opens up Microsoft's JScript REPLACE
:::  documentation within your browser.
:::
:::  If called with a single argument of /V, case insensitive, then prints
:::  the version of REPL.BAT.
:::
:::  Search  - By default, this is a case sensitive JScript (ECMA) regular
:::            expression expressed as a string.
:::
:::            JScript regex syntax documentation is available at
:::            http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx
:::
:::  Replace - By default, this is the string to be used as a replacement for
:::            each found search expression. Full support is provided for
:::            substituion patterns available to the JScript replace method.
:::
:::            For example, $& represents the portion of the source that matched
:::            the entire search pattern, $1 represents the first captured
:::            submatch, $2 the second captured submatch, etc. A $ literal
:::            can be escaped as $$.
:::
:::            An empty replacement string must be represented as "".
:::
:::            Replace substitution pattern syntax is fully documented at
:::            http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx
:::
:::  Options - An optional string of characters used to alter the behavior
:::            of REPL. The option characters are case insensitive, and may
:::            appear in any order.
:::
:::            A - Only print altered lines. Unaltered lines are discarded.
:::                If the S options is present, then prints the result only if
:::                there was a change anywhere in the string. The A option is
:::                incompatible with the M option unless the S option is present.
:::
:::            B - The Search must match the beginning of a line.
:::                Mostly used with literal searches.
:::
:::            E - The Search must match the end of a line.
:::                Mostly used with literal searches.
:::
:::            I - Makes the search case-insensitive.
:::
:::            J - The Replace argument represents a JScript expression.
:::                The expression may access an array like arguments object
:::                named $. However, $ is not a true array object.
:::
:::                The $.length property contains the total number of arguments
:::                available. The $.length value is equal to n+3, where n is the
:::                number of capturing left parentheses within the Search string.
:::
:::                $[0] is the substring that matched the Search,
:::                $[1] through $[n] are the captured submatch strings,
:::                $[n+1] is the offset where the match occurred, and
:::                $[n+2] is the original source string.
:::
:::                Arguments $[0] through $[10] may be abbreviated as
:::                $1 through $10. Argument $[11] and above must use the square
:::                bracket notation.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in the Replace string
:::                are treated as $ literals.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line, thus enabling
:::                search for \n. This also enables preservation of the original
:::                line terminators. If the M option is not present, then every
:::                printed line is terminated with carriage return and line feed.
:::                The M option is incompatible with the A option unless the S
:::                option is also present.
:::
:::                Note: If working with binary data containing NULL bytes,
:::                      then the M option must be used.
:::
:::            S - The source is read from an environment variable instead of
:::                from stdin. The name of the source environment variable is
:::                specified in the next argument after the option string. Without
:::                the M option, ^ anchors the beginning of the string, and $ the
:::                end of the string. With the M option, ^ anchors the beginning
:::                of a line, and $ the end of a line.
:::
:::            V - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences within the Replace string:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \q     -  Quote
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Extended ASCII byte code expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Also enables the \q escape sequence for the Search string.
:::                The other escape sequences are already standard for a regular
:::                expression Search string.
:::
:::                Also modifies the behavior of \xnn in the Search string to work
:::                properly with extended ASCII byte codes.
:::
:::                Extended escape sequences are supported even when the L option
:::                is used. Both Search and Replace support all of the extended
:::                escape sequences if both the X and L opions are combined.
:::
:::  Return Codes:  0 = At least one change was made
:::                     or the /? or /V option was used
:::
:::                 1 = No change was made
:::
:::                 2 = Invalid call syntax or incompatible options
:::
:::                 3 = JScript runtime error, typically due to invalid regex
:::
::: REPL.BAT was written by Dave Benham, with assistance from DosTips user Aacini
::: to get \xnn to work properly with extended ASCII byte codes. Also assistance
::: from DosTips user penpen diagnosing issues reading NULL bytes, along with a
::: workaround. REPL.BAT was originally posted at:
::: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^:::" "" a
    exit /b 0
  ) else if /i "%~1" equ "/?regex" (
    explorer "http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/?replace" (
    explorer "http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/V" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^::(REPL\.BAT version)" "$1" a
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 2
  )
)
echo(%~3|findstr /i "[^SMILEBVXAJ]" >nul && (
  call :err "Invalid option(s)"
  exit /b 2
)
echo(%~3|findstr /i "M"|findstr /i "A"|findstr /vi "S" >nul && (
  call :err "Incompatible options"
  exit /b 2
)
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%

:err
>&2 echo ERROR: %~1. Use REPL /? to get help.
exit /b

************* JScript portion **********/
var rtn=1;
try {
  var env=WScript.CreateObject("WScript.Shell").Environment("Process");
  var args=WScript.Arguments;
  var search=args.Item(0);
  var replace=args.Item(1);
  var options="g";
  if (args.length>2) options+=args.Item(2).toLowerCase();
  var multi=(options.indexOf("m")>=0);
  var alterations=(options.indexOf("a")>=0);
  if (alterations) options=options.replace(/a/g,"");
  var srcVar=(options.indexOf("s")>=0);
  if (srcVar) options=options.replace(/s/g,"");
  var jexpr=(options.indexOf("j")>=0);
  if (jexpr) options=options.replace(/j/g,"");
  if (options.indexOf("v")>=0) {
    options=options.replace(/v/g,"");
    search=env(search);
    replace=env(replace);
  }
  if (options.indexOf("x")>=0) {
    options=options.replace(/x/g,"");
    if (!jexpr) {
      replace=replace.replace(/\\\\/g,"\\B");
      replace=replace.replace(/\\q/g,"\"");
      replace=replace.replace(/\\x80/g,"\\u20AC");
      replace=replace.replace(/\\x82/g,"\\u201A");
      replace=replace.replace(/\\x83/g,"\\u0192");
      replace=replace.replace(/\\x84/g,"\\u201E");
      replace=replace.replace(/\\x85/g,"\\u2026");
      replace=replace.replace(/\\x86/g,"\\u2020");
      replace=replace.replace(/\\x87/g,"\\u2021");
      replace=replace.replace(/\\x88/g,"\\u02C6");
      replace=replace.replace(/\\x89/g,"\\u2030");
      replace=replace.replace(/\\x8[aA]/g,"\\u0160");
      replace=replace.replace(/\\x8[bB]/g,"\\u2039");
      replace=replace.replace(/\\x8[cC]/g,"\\u0152");
      replace=replace.replace(/\\x8[eE]/g,"\\u017D");
      replace=replace.replace(/\\x91/g,"\\u2018");
      replace=replace.replace(/\\x92/g,"\\u2019");
      replace=replace.replace(/\\x93/g,"\\u201C");
      replace=replace.replace(/\\x94/g,"\\u201D");
      replace=replace.replace(/\\x95/g,"\\u2022");
      replace=replace.replace(/\\x96/g,"\\u2013");
      replace=replace.replace(/\\x97/g,"\\u2014");
      replace=replace.replace(/\\x98/g,"\\u02DC");
      replace=replace.replace(/\\x99/g,"\\u2122");
      replace=replace.replace(/\\x9[aA]/g,"\\u0161");
      replace=replace.replace(/\\x9[bB]/g,"\\u203A");
      replace=replace.replace(/\\x9[cC]/g,"\\u0153");
      replace=replace.replace(/\\x9[dD]/g,"\\u009D");
      replace=replace.replace(/\\x9[eE]/g,"\\u017E");
      replace=replace.replace(/\\x9[fF]/g,"\\u0178");
      replace=replace.replace(/\\b/g,"\b");
      replace=replace.replace(/\\f/g,"\f");
      replace=replace.replace(/\\n/g,"\n");
      replace=replace.replace(/\\r/g,"\r");
      replace=replace.replace(/\\t/g,"\t");
      replace=replace.replace(/\\v/g,"\v");
      replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      replace=replace.replace(/\\B/g,"\\");
    }
    search=search.replace(/\\\\/g,"\\B");
    search=search.replace(/\\q/g,"\"");
    search=search.replace(/\\x80/g,"\\u20AC");
    search=search.replace(/\\x82/g,"\\u201A");
    search=search.replace(/\\x83/g,"\\u0192");
    search=search.replace(/\\x84/g,"\\u201E");
    search=search.replace(/\\x85/g,"\\u2026");
    search=search.replace(/\\x86/g,"\\u2020");
    search=search.replace(/\\x87/g,"\\u2021");
    search=search.replace(/\\x88/g,"\\u02C6");
    search=search.replace(/\\x89/g,"\\u2030");
    search=search.replace(/\\x8[aA]/g,"\\u0160");
    search=search.replace(/\\x8[bB]/g,"\\u2039");
    search=search.replace(/\\x8[cC]/g,"\\u0152");
    search=search.replace(/\\x8[eE]/g,"\\u017D");
    search=search.replace(/\\x91/g,"\\u2018");
    search=search.replace(/\\x92/g,"\\u2019");
    search=search.replace(/\\x93/g,"\\u201C");
    search=search.replace(/\\x94/g,"\\u201D");
    search=search.replace(/\\x95/g,"\\u2022");
    search=search.replace(/\\x96/g,"\\u2013");
    search=search.replace(/\\x97/g,"\\u2014");
    search=search.replace(/\\x98/g,"\\u02DC");
    search=search.replace(/\\x99/g,"\\u2122");
    search=search.replace(/\\x9[aA]/g,"\\u0161");
    search=search.replace(/\\x9[bB]/g,"\\u203A");
    search=search.replace(/\\x9[cC]/g,"\\u0153");
    search=search.replace(/\\x9[dD]/g,"\\u009D");
    search=search.replace(/\\x9[eE]/g,"\\u017E");
    search=search.replace(/\\x9[fF]/g,"\\u0178");
    if (options.indexOf("l")>=0) {
      search=search.replace(/\\b/g,"\b");
      search=search.replace(/\\f/g,"\f");
      search=search.replace(/\\n/g,"\n");
      search=search.replace(/\\r/g,"\r");
      search=search.replace(/\\t/g,"\t");
      search=search.replace(/\\v/g,"\v");
      search=search.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      search=search.replace(/\\B/g,"\\");
    } else search=search.replace(/\\B/g,"\\\\");
  }
  if (options.indexOf("l")>=0) {
    options=options.replace(/l/g,"");
    search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
    if (!jexpr) replace=replace.replace(/\$/g,"$$$$");
  }
  if (options.indexOf("b")>=0) {
    options=options.replace(/b/g,"");
    search="^"+search
  }
  if (options.indexOf("e")>=0) {
    options=options.replace(/e/g,"");
    search=search+"$"
  }
  var search=new RegExp(search,options);
  var str1, str2;

  if (srcVar) {
    str1=env(args.Item(3));
    str2=str1.replace(search,jexpr?replFunc:replace);
    if (!alterations || str1!=str2) if (multi) {
      WScript.Stdout.Write(str2);
    } else {
      WScript.Stdout.WriteLine(str2);
    }
    if (str1!=str2) rtn=0;
  } else if (multi){
    var buf=1024;
    str1="";
    while (!WScript.StdIn.AtEndOfStream) {
      str1+=WScript.StdIn.Read(buf);
      buf*=2
    }
    str2=str1.replace(search,jexpr?replFunc:replace);
    WScript.Stdout.Write(str2);
    if (str1!=str2) rtn=0;
  } else {
    while (!WScript.StdIn.AtEndOfStream) {
      str1=WScript.StdIn.ReadLine();
      str2=str1.replace(search,jexpr?replFunc:replace);
      if (!alterations || str1!=str2) WScript.Stdout.WriteLine(str2);
      if (str1!=str2) rtn=0;
    }
  }
} catch(e) {
  WScript.Stderr.WriteLine("JScript runtime error: "+e.message);
  rtn=3;
}
WScript.Quit(rtn);

function replFunc($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10) {
  var $=arguments;
  return(eval(replace));
}


MISE À JOUR IMPORTANTE

J'ai cessé de développer REPL.BAT et l'ai remplacé par JREPL.BAT. Ce nouvel utilitaire a toutes les mêmes fonctionnalités de REPL.BAT, et bien plus encore:

  • Prise en charge Unicode UTF-16LE via les capacités unicode CSCRIPT natives et tout autre jeu de caractères (y compris UTF-8) via ADO.
  • Lire directement depuis / écrire directement dans un fichier: pas besoin de tuyaux, de redirection ou de commande de déplacement.
  • Incorporer JScript fourni par l'utilisateur
  • Fonction de traduction similaire à unix tr, mais elle prend également en charge la recherche d'expression régulière et le remplacement JScript
  • Supprimer le texte non correspondant
  • Préfixer les lignes de sortie avec le numéro de ligne
  • et plus...

Comme toujours, une documentation complète est intégrée au script.

La solution triviale originale est maintenant encore plus simple:

jrepl "foo" "bar" /f test.txt /o -

La version actuelle de JREPL.BAT est disponible sur DosTips . Lisez tous les articles suivants dans le fil pour voir des exemples d'utilisation et un historique du développement.

dbenham
la source
Super truc! J'adore ce b / c de la simplicité et de la façon dont vous pouvez l'adapter à n'importe quel script, d'où l'écriture de code JS plutôt qu'un lot de merde.
Adaptabi
Modifier - Ajout de l'option A pour imprimer uniquement les lignes qui ont été modifiées. Également amélioré l'option X pour prendre en charge la \qreprésentation ", et les littéraux de recherche prennent désormais en charge toutes les séquences d'échappement étendues lorsque les options L et X sont combinées.
dbenham
@dbenham - +1. Il s'agit d'une approche astucieuse, elle sera également utile pour plusieurs autres tâches. Merci de l'avoir posté.
bw
EDIT - J'ai modifié le comportement de \ xnn lorsque l'option X est utilisée pour que le code représente le code d'octet ASCII étendu. Ajout d'une option de version / V.
dbenham
9
@dbenham Ceci est un joyau. Pourquoi ne le mettez-vous pas sur GitHub ou en tant que Gist? Rendrait le versionnage, les suivis, les versions / distribution, les correctifs et plus faciles. Si vous avez besoin d'aide, faites le moi savoir.
Atif Aziz
36

Utiliser FNR

Utilisez l' fnrutilitaire. Il a quelques avantages par rapport à fart:

  • Expressions régulières
  • Interface graphique en option. Possède un "bouton de génération de ligne de commande" pour créer un texte de ligne de commande à placer dans un fichier de commandes.
  • Modèles multi-lignes: L'interface graphique vous permet de travailler facilement avec des modèles multi-lignes. Dans FART, vous devez échapper manuellement les sauts de ligne.
  • Vous permet de sélectionner l'encodage des fichiers texte. Dispose également d'une option de détection automatique.

Téléchargez FNR ici: http://findandreplace.io/?z=codeplex

Exemple d'utilisation: fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"

Un homme
la source
1
C'est sympa. Être capable de générer la ligne de commande à partir de l'interface graphique est une fonctionnalité simple et agréable qui m'a permis de démarrer rapidement.
David Hammond
Outil très utile. J'ai essayé FART avant mais la documentation est obsolète.
Artur Kędzior
Outil sympa, il prend même en charge l'expression régulière. C'est quelque chose que FART manque.
Dio Phung
1
Merci d'avoir indiqué cet outil. Exe unique, excellent remplacement pour FART qui n'est plus développé (et qui manque regex); et la syntaxe PowerShell est tellement insupportable.
Gras Double
C'est très utile. Je cherchais un remplacement grep + sed dans les fenêtres, cela a très bien fonctionné!
Serban Tanasa
25

Je ne pense pas qu'il existe un moyen de le faire avec des commandes intégrées. Je vous suggère de télécharger quelque chose comme Gnuwin32 ou UnxUtils et d'utiliser la sedcommande (ou télécharger uniquement sed):

sed -c s/FOO/BAR/g filename
Ferruccio
la source
2
Utilisez cygwin ( cygwin.com ). C'est la meilleure chose à faire pour installer Linux.
Andrew Johnson
Il est préférable de proposer une solution qui ne repose pas sur l'installation de cygwin. La manipulation de chaînes POSIX est une évidence - faire cela sur Windows est un peu plus obscur.
Rex
4
Gnuwin32 et UnxUtils sont des binaires autonomes conçus pour Windows. Ils ne dépendent pas de cygwin.
Ferruccio
1
cygwin: sed -i -b -e 's/FOO/BAR/g' `find . -name *.txt`-i - éditer le fichier sur place; -b - ne traite pas CR + LF - sans cette option, CR + LF serait converti en LF
Alexey Vishentsev
@AndrewJohnson L'opinion et l'information sont deux choses différentes.
Preza8
21

Je sais que je suis en retard à la fête ..

Personnellement, j'aime la solution chez: - http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

Nous utilisons également largement la fonction de déduplication pour nous aider à envoyer quotidiennement environ 500 e-mails via SMTP à partir de: - https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

et ces deux fonctionnent en mode natif sans outils ou utilitaires supplémentaires nécessaires.

REMPLACER:

DEL New.txt
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (OLD.txt) do (
Set str=%%a
set str=!str:FOO=BAR!
echo !str!>>New.txt
)
ENDLOCAL

DÉDUPLICATEUR (notez l'utilisation de -9 pour un numéro ABA):

REM DE-DUPLICATE THE Mapping.txt FILE
REM THE DE-DUPLICATED FILE IS STORED AS new.txt

set MapFile=Mapping.txt
set ReplaceFile=New.txt

del %ReplaceFile%
::DelDupeText.bat
rem https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o
setLocal EnableDelayedExpansion
for /f "tokens=1,2 delims=," %%a in (%MapFile%) do (
set str=%%a
rem Ref: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.RightString
set str=!str:~-9!
set str2=%%a
set str3=%%a,%%b

find /i ^"!str!^" %MapFile%
find /i ^"!str!^" %ReplaceFile%
if errorlevel 1 echo !str3!>>%ReplaceFile%
)
ENDLOCAL

Merci!

Leptonator
la source
le script batch ne fait qu'une simple copie de fichier - aussi: pourquoi vous remerciez-vous?
specializt
La demande initiale était de remplacer "FOO" par "BAR" dans un fichier texte en utilisant un script batch et avec des fonctions de préférence intégrées. Si je remerciais le post de Google Groupes, j'avais trouvé ce qui fonctionnait fantastique et nous l'utilisons toujours à ce jour. En outre, consultez les publications et les réponses comme celles-ci comme étant également utiles pour les utilisateurs. Je n'arrive pas à voir votre commentaire sur la copie de fichiers .. Bien sûr, il prend le contenu d'un fichier et renvoie le résultat dans un autre fichier, mais en fonction des données, il coupe et analyse les informations nécessaires. Je recommanderais de l'essayer d'abord. ;)
Leptonator
c'est essentiellement un outil de copie de fichiers qui remplace deux chaînes statiques - vous auriez pu au moins y placer deux variables pour que les personnes qui veulent l' essayer n'aient pas besoin de comprendre la syntaxe pour pouvoir réellement l'utiliser - également: les hypothèses sur Internet sont presque toujours complètement fausses. N'oubliez pas cela.
specializt
4
@specializt - S'il vous plaît ... Je ne suis pas ici pour débattre de la sémantique. Si vous le souhaitez, pouvons-nous mettre cela hors ligne dans la salle de chat.
Leptonator
2
À mon avis, c'est la réponse à la question initiale. J'utiliserai cette astuce pour configurer les fichiers d'initialisation d'un service lors de l'installation et je ne voudrais pas activer PowerShell ou permettre au moteur de script de s'exécuter sur mes serveurs. Donc, souvent, répond aux questions liées à Windows, commencez par "installer ce gadget à partir de là" car il y a toujours une attitude "PC".
mico
15

Lorsque vous travaillez avec Git sur Windows, lancezgit-bash et utilisez simplement sed. Ou, lorsque vous utilisez Windows 10, démarrez "Bash sur Ubuntu sur Windows" (à partir du sous-système Linux) et utilisezsed .

C'est un éditeur de flux, mais peut éditer des fichiers directement en utilisant la commande suivante:

sed -i -e 's/foo/bar/g' filename
  • -i L'option est utilisée pour modifier en place sur le nom de fichier.
  • -e option indique une commande à exécuter.
    • sest utilisé pour remplacer l'expression trouvée "foo" par "bar" et gest utilisé pour remplacer toutes les correspondances trouvées.

Note d'ereOn:

Si vous souhaitez remplacer une chaîne dans les fichiers versionnés uniquement d'un référentiel Git, vous pouvez utiliser:

git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'

qui fait des merveilles.

Jens A. Koch
la source
1
Notez que si vous effectuez ce changement de nom dans un référentiel git et que vous souhaitez uniquement le remplacer dans des fichiers versionnés, vous pouvez le faire: git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'ce qui fonctionne à merveille.
ereOn
13

J'ai joué avec certaines des réponses existantes ici et préfère ma solution améliorée ...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }"

ou si vous souhaitez enregistrer à nouveau la sortie dans un fichier ...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }" > outputFile.txt

L'avantage de ceci est que vous pouvez diriger la sortie de n'importe quel programme. Va chercher à utiliser des expressions régulières avec cela aussi. Impossible de savoir comment en faire un fichier BAT pour une utilisation plus facile ... :-(

Simon East
la source
3
C'est une bonne solution. Malheureusement, l'utilisation typesignifie que toutes les lignes de plus de 80 caractères sont encapsulées. Quelle douleur.
sirdank
12

J'ai utilisé Perl, et cela fonctionne à merveille.

perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" <fileName>

.orig est l'extension qu'il ajouterait au fichier d'origine

Pour un certain nombre de fichiers correspondant tels que * .html

for %x in (<filePattern>) do perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" %x
Faisal
la source
Ceci est la solution la plus simple +1, lors de la conversion de sh en bat, remplacez-le sedpar perl -pi.backup -eet appréciez-le :)
Yann39
11

Avec le replacer.bat

1) Avec e?option qui évaluera les séquences de caractères spéciaux comme les \n\rséquences unicode. Dans ce cas, remplacera le devis "Foo"et "Bar":

call replacer.bat "e?C:\content.txt" "\u0022Foo\u0022" "\u0022Bar\u0022"

2) Remplacement simple là où le Fooet Barne sont pas cités.

call replacer.bat "C:\content.txt" "Foo" "Bar"
npocmaka
la source
Ça ne fonctionne pas pour moi. Comment gérez-vous cela? Je reçois l'erreur «replace_in_config.bat» n'est pas reconnu comme une commande interne ou externe, un programme exploitable ou un fichier de commandes.
FrenkyB
@FrenkyB - il doit être dans le même répertoire que celui où vous l'appelez ou dans le chemin d'accès - ss64.com/nt/path.html
npocmaka
J'ai eu les trois fichiers dans le même répertoire.
FrenkyB
9

Voici une solution que j'ai trouvée travaillé sur Win XP. Dans mon fichier de commandes en cours d'exécution, j'ai inclus les éléments suivants:

set value=new_value

:: Setup initial configuration
:: I use && as the delimiter in the file because it should not exist, thereby giving me the whole line
::
echo --> Setting configuration and properties.
for /f "tokens=* delims=&&" %%a in (config\config.txt) do ( 
  call replace.bat "%%a" _KEY_ %value% config\temp.txt 
)
del config\config.txt
rename config\temp.txt config.txt

Le replace.batfichier est comme ci-dessous. Je n'ai pas trouvé de moyen d'inclure cette fonction dans le même fichier de commandes, car la %%avariable semble toujours donner la dernière valeur dans la boucle for.

replace.bat:

@echo off

:: This ensures the parameters are resolved prior to the internal variable
::
SetLocal EnableDelayedExpansion

:: Replaces Key Variables
::
:: Parameters:
:: %1  = Line to search for replacement
:: %2  = Key to replace
:: %3  = Value to replace key with
:: %4  = File in which to write the replacement
::

:: Read in line without the surrounding double quotes (use ~)
::
set line=%~1

:: Write line to specified file, replacing key (%2) with value (%3)
::
echo !line:%2=%3! >> %4

:: Restore delayed expansion
::
EndLocal
Tchad
la source
1
Malheureusement, cela saute également les lignes vides. Une fonctionnalité de la commande {{for}}.
John Rocha
7

Jetez un oeil à Y at -il un utilitaire sed comme pour cmd.exe qui a demandé un équivalent sed sous Windows, devrait également s'appliquer à cette question. Résumé:

  • Cela peut être fait dans un fichier batch, mais ce n'est pas joli
  • Beaucoup d'exécutables tiers disponibles qui le feront pour vous, si vous avez le luxe d'installer ou simplement de copier sur un exe
  • Peut être fait avec VBScript ou similaire si vous avez besoin de quelque chose capable de fonctionner sur une boîte Windows sans modification, etc.
Geai
la source
4

Peut-être un peu en retard, mais je recherche souvent des choses similaires, car je ne veux pas passer par la douleur de faire approuver un logiciel.

Cependant, vous utilisez généralement l'instruction FOR sous différentes formes. Quelqu'un a créé un fichier de commandes utile qui effectue une recherche et un remplacement. Jetez un oeil ici . Il est important de comprendre les limites du fichier de commandes fourni. Pour cette raison, je ne copie pas le code source dans cette réponse.

Peter Schuetze
la source
4

Deux fichiers batch qui fournissent des search and replacefonctions ont été écrits par les membres de Stack Overflow dbenhamet aaciniutilisés native built-in jscriptdans Windows.

Ils sont à la fois robustet very swift with large filescomparés aux scripts batch simples, et également simplerà utiliser pour le remplacement de base du texte. Ils ont tous deux une Windows regular expressioncorrespondance de motifs.

  1. Ce sed-likefichier batch d'aide est appelé repl.bat(par dbenham).

    Exemple d'utilisation du Lcommutateur littéral:

    echo This is FOO here|repl "FOO" "BAR" L
    echo and with a file:
    type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
    
  2. Ce grep-likefichier batch d'aide est appelé findrepl.bat(par aacini).

    Exemple avec des expressions régulières actives:

    echo This is FOO here|findrepl "FOO" "BAR" 
    echo and with a file:
    type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"
    

Les deux deviennent de puissants utilitaires à l'échelle du système when placed in a folder that is on the pathou peuvent être utilisés dans le même dossier avec un fichier de commandes ou à partir de l'invite cmd.

Ils ont tous deux des case-insensitivecommutateurs et de nombreuses autres fonctions.

Foxidrive
la source
3

La commande Power Shell fonctionne comme un charme

(
test.txt | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt
)
kool_guy_here
la source
3

Je viens de faire face à un problème similaire - "Rechercher et remplacer du texte dans des fichiers", mais à l'exception que pour les noms de fichiers et la recherche / réparation, je dois utiliser l'expression régulière. Parce que je ne suis pas familier avec Powershell et que je souhaite enregistrer mes recherches pour une utilisation ultérieure, j'ai besoin de quelque chose de plus "convivial" (préférable s'il a une interface graphique).

Donc, pendant la recherche sur Google :), j'ai trouvé un excellent outil - FAR (Find And Replace) (pas FART).

Ce petit programme possède une interface graphique agréable et prend en charge l'expression régulière pour la recherche dans les noms de fichiers et dans les fichiers. Le seul inconvénient est que si vous souhaitez enregistrer vos paramètres, vous devez exécuter le programme en tant qu'administrateur (au moins sur Win7).

madcorp
la source
C'est la même réponse que la réponse de 2010 @VonC Dans ce fil
jeb
@jeb J'ai souligné que FAR n'est pas FART - deux programmes différents avec des noms presque identiques. FAR a l' interface graphique et peut fonctionner avec regex, alors que dans les commentaires ci - dessous que fil les gens mentionnent que FART ne regex soutien.
madcorp
3

Je préfère utiliser sedd' utilitaires GNU pour Win32 , les points suivants doivent noter

  • le guillemet simple ''ne fonctionnera pas dans les fenêtres, utilisez ""plutôt
  • sed -ine fonctionnera pas sous Windows, il faudra échanger des fichiers

Donc, le code de travail sedpour rechercher et remplacer du texte dans un fichier dans Windows est comme ci-dessous

sed -e "s/foo/bar/g" test.txt > tmp.txt && mv tmp.txt test.txt
Chetabahana
la source
2
Avant que les utilisateurs de Windows ne fassent immédiatement l'échange de fichiers: les nouvelles versions de sed prennent en charge l'édition sur place avec -i! Si votre version sed le fait, vérifiez la commande à partir de cette réponse: stackoverflow.com/a/33762001/2492801 .
Benjamin Bihler
2

C'est une chose que les scripts batch ne font tout simplement pas bien.

Le script morechilli lié à fonctionnera pour certains fichiers, mais malheureusement il s'étouffera avec ceux qui contiennent des caractères tels que des tuyaux et des esperluettes.

VBScript est un meilleur outil intégré pour cette tâche. Voir cet article pour un exemple: http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx


la source
2

@Rachel a donné une excellente réponse, mais en voici une variante pour lire le contenu d'une $datavariable PowerShell . Vous pouvez ensuite manipuler facilement le contenu plusieurs fois avant d'écrire dans un fichier de sortie. Voir également comment les valeurs multilignes sont données dans un fichier batch .bat.

@REM ASCII=7bit ascii(no bom), UTF8=with bom marker
set cmd=^
  $old = '\$Param1\$'; ^
  $new = 'Value1'; ^
  [string[]]$data = Get-Content 'datafile.txt'; ^
  $data = $data -replace $old, $new; ^
  out-file -InputObject $data -encoding UTF8 -filepath 'datafile.txt';
powershell -NoLogo -Noninteractive -InputFormat none -Command "%cmd%"
Qui
la source
2

Utilisez PowerShell dans .bat - pour Windows 7+

l'encodage utf8 est facultatif, bon pour les sites Web

@echo off
set ffile='myfile.txt'
set fold='FOO'
set fnew='BAR'
powershell -Command "(gc %ffile%) -replace %fold%, %fnew% | Out-File %ffile% -encoding utf8"
Wagner Pereira
la source
1

Téléchargez Cygwin (gratuit) et utilisez des commandes de type Unix sur la ligne de commande Windows.

Votre meilleur pari: sed

jm.
la source
10
Cygwin est mauvais. Ne l'installez pas. Mieux utiliser UnixUtils mentionné ci-dessous.
zedoo
24
Qu'est-ce qui est si mal à ce sujet?
jm.
@jm Peut-être parce que vous devez installer le tout ensemble au lieu d'utiliser un seul exécutable quand vous le souhaitez.
Andry
Mieux utiliser PowerShell, il est en fait intégré aux fenêtres.
Preza8
0

Peut également voir les outils Replace et ReplaceFilter sur https://zoomicon.github.io/tranXform/ (source incluse). Le 2ème est un filtre.

L'outil qui remplace les chaînes dans les fichiers est en VBScript (nécessite Windows Script Host [WSH] pour s'exécuter dans les anciennes versions de Windows)

Le filtre ne fonctionne probablement pas avec Unicode, sauf si vous recompilez avec la dernière version de Delphi (ou avec FreePascal / Lazarus)

George Birbilis
la source
-5

J'ai rencontré ce problème plusieurs fois lors du codage sous Visual C ++. Si vous l'avez, vous pouvez utiliser l'utilitaire Visual Studio Find and Replace. Il vous permet de sélectionner un dossier et de remplacer le contenu de tout fichier de ce dossier par tout autre texte de votre choix.

Sous Visual Studio: Édition -> Rechercher et remplacer Dans la boîte de dialogue ouverte, sélectionnez votre dossier et remplissez les cases "Rechercher quoi" et "Remplacer par". J'espère que cela vous sera utile.

Nadjib
la source
2
Nadjib, votre réponse n'aide pas l'utilisateur car vous supposez qu'il utilise un logiciel dont il ne fait aucune mention. Veuillez suggérer une option qui ne nécessite pas de logiciel.
2015
@Aibrean la réponse est inutile, mais pas pour cette raison, c'est le point d'entrée qui est faux.
Paul