Come è possibile trovare e sostituire il testo in un file utilizzando l'ambiente della riga di comando di Windows?


492

Sto scrivendo uno script di file batch utilizzando l'ambiente della riga di comando di Windows e voglio cambiare ogni occorrenza di un po 'di testo in un file (es. "FOO") con un altro (es. "BAR"). Qual è il modo più semplice per farlo? Qualche funzione integrata?



usa questo:echo(%text:%search%=%replace%%)
scientist_7

Risposte:


308

Molte delle risposte qui mi hanno aiutato a indicarmi la giusta direzione, tuttavia nessuna era adatta a me, quindi sto pubblicando la mia soluzione.

Ho Windows 7, fornito con PowerShell integrato. Ecco lo script che ho usato per trovare / sostituire tutte le istanze di testo in un file:

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

Per spiegarlo:

  • powershell avvia powershell.exe, incluso in Windows 7
  • -Command "... " è un arg della riga di comando per powershell.exe contenente il comando da eseguire
  • (gc myFile.txt)legge il contenuto di myFile.txt( gcè l'abbreviazione di Get-Contentcomando)
  • -replace 'foo', 'bar'esegue semplicemente il comando di sostituzione foocon cui sostituirebar
  • | Out-File myFile.txt convoglia l'output nel file myFile.txt
  • -encoding ASCII impedisce la trascrizione del file di output in Unicode, come sottolineano i commenti

Powershell.exe dovrebbe essere già parte dell'istruzione PATH, ma in caso contrario è possibile aggiungerlo. La posizione sul mio computer èC:\WINDOWS\system32\WindowsPowerShell\v1.0


71
Attenzione, questo comando può anche transcodificare il file in codifica Unicode. È possibile specificare manualmente la codifica aggiungendo -encoding ASCIIo UTF8o qualsiasi altra cosa sia necessaria. Inoltre, se scegli come target UTF8, all'inizio del file potrebbe non apparire un Byte Order Mark che non era presente nell'originale.
Wyck,

78
@Wyck Mi ci è voluto un po 'per capire dove mettere -encoding ASCII. Per chiunque ne avesse bisogno in futuro, sarebbeOut-File -encoding ASCII myFile.txt
rwilson04,

15
L'unica cosa che dovevo cambiare era usare Set-Contentinvece di Out-File.
Kurtzmarc,

6
Funziona, ma le prestazioni sono terribili anche su un breve elenco di file.
jsuddsjr,

23
Attenzione che il token di sostituzione ('pippo' in questo caso) viene trattato come un'espressione regolare. Se hai dei caratteri speciali lì (avevo []), devi anteporre loro con una \ (barra rovesciata).
JW

183

Se sei su una versione di Windows che supporta .Net 2.0, sostituirei la tua shell. PowerShell ti offre tutta la potenza di .Net dalla riga di comando. Ci sono anche molti commandlet integrati. L'esempio seguente risolverà la tua domanda. Sto usando i nomi completi dei comandi, ci sono alias più brevi, ma questo ti dà qualcosa a Google per.

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

10
Vedo che PowerShell è in grado di archiviare questo. Ma come posso farlo funzionare da un file batch (esempio: myProc.bat)?
Pablo Venturino,

3
@Pablo, usa powershell.exe e avvolgi il comando ps in un singolo parametro
lubos hasko

56
-1 .. Sicuramente la risposta è stata accettata, ma non è la risposta alla domanda specificata.
baash05,

28
Ciò fallirà con un errore di file in uso se si salva nello stesso file. È necessario modificare il comando powershell in: (Get-Content test.txt) | ForEach-Object {$ _ -replace "foo", "bar"} | Set-Content test.txt
BigMomma

6
Vedi la risposta di @Rachel:powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | sc myFile.txt"
Nigel Touch

161

Basta utilizzato FART ( " F ind A ND R eplace T ext" utilità della riga di comando):
eccellente piccolo freeware per la sostituzione del testo all'interno di un grande insieme di file.

I file di installazione sono su SourceForge .

Esempio di utilizzo:

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

visualizzerà in anteprima le sostituzioni da eseguire in modo ricorsivo nei file di questa distribuzione Perl.

Unico problema: l'icona del sito Web FART non è esattamente di buon gusto, raffinata o elegante;)


Aggiornamento 2017 (7 anni dopo) jagb sottolinea nei commenti all'articolo del 2011 " FARTing the Easy Way - Trova e sostituisci testo " da Mikail Tunç


19
La cosa bella è che è un singolo exe. Nessuna dipendenza. Nessuna piccola stampa. Super facile da implementare.
Serge Wautier,

2
Molto leggero e facile da usare, ma speravo che stampasse i punti esatti in cui avvenivano le sostituzioni. Non riuscire a vederlo mi ha dato un senso di insicurezza.
William Niu,

4
Grazie, è perfetto, dovrebbe far parte degli strumenti dos standard e ha funzionato a meraviglia. L'opzione -p tuttavia non mostra quante modifiche "farebbe" e riporta sempre 0 che mi ha lanciato per qualche minuto
sradforth

3
Capisco che questa è una domanda molto vecchia, ma ho trovato ulteriori informazioni e spero che possa essere utile per gli utenti di Stack Overflow. Solo un altro link per FART in cui il prodotto è ben spiegato: FART ha spiegato @ emtunc.org e un'altra pagina può essere trovata qui: FART Si prega di fare attenzione con la sostituzione di /e 'poiché questo non funziona per tutti noi , per me ha funzionato in alcuni casi, ma non ha funzionato su alcuni file e non so perché .. L'ho usato per sostituire il testo con altri testi e un/
jagb

4
@jagb Grazie. Ho incluso il tuo link nella risposta per una maggiore visibilità.
VonC

128

Sostituisci - Sostituisci una sottostringa usando la sostituzione stringa Descrizione: per sostituire una sottostringa con un'altra stringa usa la funzione di sostituzione stringa. L'esempio mostrato qui sostituisce tutte le occorrenze "the" errori di ortografia con "the" nella variabile stringa str.

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

Output dello script:

teh cat in teh hat
the cat in the hat

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


30
In che modo è migliore la proposta sed? Questa sembra essere la risposta più semplice di tutte e non richiede l'installazione di nulla.
Don Becker

5
È possibile eseguire qualsiasi tipo di corrispondenza del modello qui? Caratteri jolly, Regex ecc.?
Keyo,

27
"In che modo è migliore la proposta di sed?" - sed e utilità simili operano su file; questo frammento omette l'importante passaggio della lettura delle righe dal file di input e della scrittura nel file di output, garantendo nel contempo che tutti i caratteri speciali nel file vengano gestiti correttamente.
Joe,

7
@Asad, sì, è vero, l'OP stava chiedendo dei file, ma in realtà funziona con flussi che non devono essere file. Ma il mio punto qui è che questa risposta è errata, poiché omette la lettura / scrittura da un flusso e la gestione di caratteri speciali.
Joe

4
@Bill come usare la variabile come testo sostitutivo? vale a dire. Ho valore in una variabile e una stringa che ha delimitatore. set str =% str: "##" =% varValue %% non funziona. Qualche soluzione alternativa?
MalTec,

55

Crea file repl.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

Per utilizzare questo script rivisto (che chiameremo sostituire.vbs) basta digitare un comando simile a questo dal prompt dei comandi:

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


questo è pulito, consente l'uso di RegEx?
user280109

3
@ user280109 Sì, supporta VBScript RegExp. È possibile utilizzare questo per sostituire usando un'espressione regolare: With (New RegExp): strNewText = .Replace(strText, strOldText, strNewText): End With. È possibile ottenere il testo dei primi 9 gruppi di cattura usando $1, $2... $9.
Spazzolino da denti,

2
VBScript è spesso trascurato (e odiato), ma è disponibile su tutte le piattaforme Windows, è molto leggibile e in realtà ha capacità molto potenti +1
zelanix

1
@ user280109 Hai appena dato il comando, quello che mi serve. Ma voglio sostituire (senza distinzione tra maiuscole e minuscole) Puoi fornire il comando per quello?
Ajmal Praveen,

49

BatchSubstitute.batsu dostips.com è un esempio di ricerca e sostituzione utilizzando un file batch puro.

Esso utilizza una combinazione di FOR, FINDe CALL SET.

Le righe che contengono caratteri tra "&<>]|^possono essere trattate in modo errato.



8
Devo mettere in dubbio l'utilità di un sito di frammenti di codice i cui termini d'uso vietano la copia di qualsiasi codice ("Non è possibile distribuire alcuna informazione fornita sotto il dominio dostips.com in qualsiasi forma senza espressa autorizzazione scritta del proprietario del dominio.") .
Gilles 'SO- smetti di essere malvagio'

1
Sono d'accordo che i loro termini sono confusi, dicono anche "Le informazioni fornite sotto il dominio dostips.com sono sperabilmente utili", quindi la mia ipotesi è che siano felici che le persone copino il codice per risolvere un problema. Non sono sicuro di aver mai letto i termini e le condizioni e di essere stato felice ...
Morechilli,

5
Questo è fantastico Adoro le risposte che non implicano il download di qualcos'altro per farlo.
Ruairi O'Brien l'

Mi piacciono anche le soluzioni che non coinvolgono utility esterne, purtroppo continuo a ricevere "find: predicate invalid ''" quando provo a eseguire questo batch. Non ho davvero il tempo di eseguire il debug in questo momento.
Jahmic,

2
L'errore "trova: predicato non valido" era dovuto a un'utilità esterna "trova" sul mio sistema. Una volta rimosso, ha funzionato bene.
Jahmic,

47

Nota : assicurati di vedere l'aggiornamento alla fine di questa risposta per un collegamento al JREPL.BAT superiore che sostituisce REPL.BAT
JREPL.BAT 7.0 e versioni successive supporta nativamente Unicode (UTF-16LE) tramite l' /UTFopzione, così come qualsiasi altri set di caratteri, incluso UTF-8, tramite ADO !!!!


Ho scritto una piccola utility ibrida JScript / batch chiamata REPL.BAT che è molto conveniente per modificare i file ASCII (o ASCII esteso) tramite la riga di comando o un file batch. Lo script puramente nativo non richiede l'installazione di alcun eseguibile di terze parti e funziona su qualsiasi versione di Windows moderna da XP in poi. È anche molto veloce, soprattutto se paragonato a soluzioni batch pure.

REPL.BAT legge semplicemente lo stdin, esegue una ricerca regex JScript e sostituisce e scrive il risultato su stdout.

Ecco un esempio banale di come sostituire foo con bar in test.txt, supponendo che REPL.BAT sia nella cartella corrente o, meglio ancora, da qualche parte all'interno del PERCORSO:

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

Le funzionalità regex di JScript lo rendono molto potente, in particolare la capacità del testo sostitutivo di fare riferimento a sottostringhe acquisite dal testo di ricerca.

Ho incluso un numero di opzioni nell'utilità che lo rendono abbastanza potente. Ad esempio, combinando le opzioni Me si Xabilita la modifica dei file binari! L' Mopzione multilinea consente di effettuare ricerche su più righe. L' Xopzione modello di sostituzione eXtended fornisce sequenze di escape che consentono l'inclusione di qualsiasi valore binario nel testo sostitutivo.

L'intera utility potrebbe essere stata scritta come puro JScript, ma il file batch ibrido elimina la necessità di specificare esplicitamente CSCRIPT ogni volta che si desidera utilizzare l'utilità.

Ecco lo script REPL.BAT. La documentazione completa è incorporata nello 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));
}


AGGIORNAMENTO IMPORTANTE

Ho smesso di sviluppare REPL.BAT e l'ho sostituito con JREPL.BAT. Questa nuova utility ha tutte le stesse funzionalità di REPL.BAT, oltre a molte altre:

  • Supporto Unicode UTF-16LE tramite funzionalità Unicode CSCRIPT native e qualsiasi altro set di caratteri (incluso UTF-8) tramite ADO.
  • Leggi direttamente da / scrivi direttamente in un file: nessuna necessità di pipe, reindirizzamento o comando di spostamento.
  • Incorporare JScript fornito dall'utente
  • Funzionalità di traduzione simile a unix tr, solo che supporta anche la ricerca regex e la sostituzione JScript
  • Elimina il testo non corrispondente
  • Prefisso linee di uscita con numero di linea
  • e altro ancora ...

Come sempre, la documentazione completa è incorporata nello script.

La banale soluzione originale è ora ancora più semplice:

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

La versione corrente di JREPL.BAT è disponibile su DosTips . Leggi tutti i post successivi nel thread per vedere esempi di utilizzo e una cronologia dello sviluppo.


Roba fantastica! Adoro questo b / c della semplicità e del modo in cui puoi adattarlo a qualsiasi script, quindi scrivere codice JS che batch scadente.
Adaptabi,

Modifica: aggiunta l'opzione A per stampare solo le linee modificate. È stata inoltre migliorata l'opzione X per supportare la \qrappresentazione "e i letterali di ricerca ora supportano tutte le sequenze di escape estese quando vengono combinate le opzioni L e X.
dbenham,

@dbenham - +1. Questo è un approccio semplice, utile anche per molte altre attività. Grazie per averlo pubblicato.
bw

EDIT - Ho modificato il comportamento di \ xnn quando si utilizza l'opzione X in modo che il codice rappresenti il ​​codice byte ASCII esteso. Aggiunta anche un'opzione di versione / V.
dbenham,

9
@dbenham Questo è un gioiello. Perché non lo metti su GitHub o come Gist? Renderebbe il controllo delle versioni, follow-up, rilasci / distribuzione, correzioni e più facili. Se hai bisogno di aiuto, fammelo sapere.
Atif Aziz,

36

Usa FNR

Usa l' fnrutilità. Ha alcuni vantaggi rispetto a fart:

  • Espressioni regolari
  • GUI opzionale. Dispone di un "pulsante Genera riga di comando" per creare il testo della riga di comando da inserire nel file batch.
  • Schemi multilinea: la GUI consente di lavorare facilmente con schemi multilinea. In FART dovresti sfuggire manualmente alle interruzioni di riga.
  • Consente di selezionare la codifica del file di testo. Ha anche un'opzione di rilevamento automatico.

Scarica FNR qui: http://findandreplace.io/?z=codeplex

Esempio di utilizzo: fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"


1
Questo è carino. Essere in grado di generare la riga di comando dalla GUI è una bella e semplice funzione che mi ha fatto andare rapidamente.
David Hammond,

Strumento molto utile. Ho provato FART prima ma la documentazione non è aggiornata.
Artur Kędzior,

Strumento interessante, supporta persino l'espressione regolare. Questo è qualcosa che manca a FART.
Dio Phung,

1
Grazie per aver indicato questo strumento. Exe singolo, ottimo sostituto di FART che non è più sviluppato (e manca regex); e la sintassi di PowerShell è così insopportabile.
Gras Double

Questo è molto utile Cercavo grep + sed sostituzione in windows, funzionava benissimo!
Serban Tanasa,

25

Non credo che ci sia un modo per farlo con qualsiasi comando integrato. Ti suggerirei di scaricare qualcosa come Gnuwin32 o UnxUtils e utilizzare il sedcomando (o solo download sed):

sed -c s/FOO/BAR/g filename

2
Usa cygwin ( cygwin.com ). È la prossima cosa migliore per installare effettivamente Linux.
Andrew Johnson,

È meglio se si può fornire una soluzione che non si basa sull'installazione di Cygwin. La manipolazione delle stringhe POSIX è un gioco da ragazzi: farlo su Windows è un po 'più oscuro.
Rex,

4
Gnuwin32 e UnxUtils sono file binari autonomi creati per Windows. Non dipendono da Cygwin.
Ferruccio,

1
cygwin: sed -i -b -e 's/FOO/BAR/g' `find . -name *.txt`-i - modifica il file sul posto; -b - non elaborare CR + LF - senza questa opzione CR + LF verrebbe convertito in LF
Alexey Vishentsev

@AndrewJohnson Opinione e informazioni sono due cose diverse.
Preza8

21

So di essere in ritardo alla festa ..

Personalmente, mi piace la soluzione su: - http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

Inoltre, utilizziamo ampiamente la funzione Dedupe per aiutarci a consegnare circa 500 e-mail ogni giorno tramite SMTP da: - https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

e entrambi funzionano in modo nativo senza bisogno di strumenti o utilità extra.

sostituto:

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

DEDUPLICATORE (notare l'uso di -9 per un numero 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

Grazie!


lo script batch non fa altro che una semplice copia di file - anche: perché ti ringrazi?
specializt

La richiesta originale era di sostituire "FOO" con "BAR" in un file di testo usando uno script batch e con funzioni incorporate preferibilmente. Semmai ringraziando il post di Google Gruppi avevo scoperto che funziona alla grande e lo usiamo ancora oggi. Inoltre, vedi post e risposte come questi utili anche per gli utenti che arrivano lungo la strada. Non riesco a vedere il tuo commento sulla copia del file. Certo, prende il contenuto di un file e fa eco al risultato in un altro file, ma in base ai dati, taglia e analizza le informazioni necessarie. Consiglierei di provarlo prima. ;)
Leptonator,

è fondamentalmente uno strumento di copia di file che sostituisce due stringhe statiche - potresti almeno aver inserito due variabili lì in modo che le persone che vogliono provarlo non avranno bisogno di capire la sintassi per essere effettivamente in grado di usarlo - inoltre: le ipotesi su Internet sono quasi sempre completamente sbagliate. Ricordati che.
specializt

4
@specializt - Per favore ... Non sono qui per discutere di semantica. Se lo desideri, possiamo portarlo offline nella chat room.
Leptonator,

2
Secondo me, questa è la risposta alla domanda originale. Userò questo suggerimento per configurare i file di inizializzazione per un servizio durante l'installazione e non vorrei abilitare PowerShell o consentire l'esecuzione del motore di scripting sui miei server. Così spesso risponde a domande relative a Windows, inizia con "installa questo gizmo da lì" in quanto c'è ancora un atteggiamento "PC" in giro.
mico,

15

Quando lavori con Git su Windows, accendi git-bash e usa semplicemente sed. Oppure, quando si utilizza Windows 10, avviare "Bash su Ubuntu su Windows" (dal sottosistema Linux) e utilizzare sed.

È un editor di stream, ma può modificare i file direttamente utilizzando il seguente comando:

sed -i -e 's/foo/bar/g' filename
  • -i opzione viene utilizzata per modificare sul posto sul nome del file.
  • -e opzione indica un comando da eseguire.
    • sviene utilizzato per sostituire l'espressione trovata "pippo" con "barra" e gviene utilizzata per sostituire qualsiasi corrispondenza trovata.

Nota di ereOn:

Se si desidera sostituire una stringa nei file con versione solo di un repository Git, è possibile utilizzare:

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

che fa miracoli.


1
Si noti che se si sta effettivamente eseguendo tale ridenominazione in un repository git e si desidera sostituire solo i file con versione, è possibile che si desideri fare: git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'che funziona a meraviglia.
Il

13

Ho giocato con alcune delle risposte esistenti qui e preferisco la mia soluzione migliorata ...

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

o se si desidera salvare nuovamente l'output in un file ...

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

Il vantaggio di ciò è che è possibile reindirizzare l'output da qualsiasi programma. Esamineremo l'uso di espressioni regolari anche con questo. Non è stato possibile capire come trasformarlo in un file BAT per un uso più semplice ... :-(


3
Questa è una buona soluzione Sfortunatamente, l'utilizzo typesignifica che tutte le righe superiori a 80 caratteri vengono spostate. Che dolore.
sirdank,

12

Ho usato il perl e funziona meravigliosamente.

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

.orig è l'estensione che aggiungerebbe al file originale

Per un numero di file corrispondenti come * .html

for %x in (<filePattern>) do perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" %x

Questa è la soluzione più semplice +1, durante la conversione da sh a pipistrello, basta sostituire sedcon perl -pi.backup -ee lo apprezzano :)
Yann39

11

Con il replacer.bat

1) Con e?opzione che valuterà sequenze di caratteri speciali come \n\re sequenze unicode. In questo caso sostituirà quotato "Foo"e "Bar":

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

2) Sostituzione semplice dove Fooe Barnon sono quotati.

call replacer.bat "C:\content.txt" "Foo" "Bar"

non funziona per me. Come si esegue questo? Ricevo l'errore "replace_in_config.bat" non riconosciuto come comando interno o esterno, programma eseguibile o file batch.
FrenkyB,

@FrenkyB - deve trovarsi nella stessa directory in cui lo chiami o nel percorso - ss64.com/nt/path.html
npocmaka

Ho avuto tutti e tre i file nella stessa directory.
FrenkyB,

9

Ecco una soluzione che ho trovato funzionante su Win XP. Nel mio file batch in esecuzione, ho incluso quanto segue:

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

Il replace.batfile è come di seguito. Non ho trovato il modo di includere quella funzione nello stesso file batch, perché la %%avariabile sembra sempre dare l'ultimo valore nel ciclo 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

1
Purtroppo questo salta anche le righe vuote. Una funzione del comando {{for}}.
John Rocha,

7

Dai un'occhiata a C'è qualche utilità simile a sed per cmd.exe che ha richiesto un equivalente sed in Windows, dovrebbe applicarsi anche a questa domanda. Sintesi:

  • Può essere fatto in file batch, ma non è carino
  • Molti eseguibili di terze parti disponibili che lo faranno per te, se hai il lusso di installare o semplicemente copiare su un exe
  • Può essere fatto con VBScript o simili se hai bisogno di qualcosa in grado di funzionare su una finestra di Windows senza modifiche, ecc.

4

Potrebbe essere un po 'tardi, ma frequentemente cerco cose simili, dal momento che non voglio superare il dolore di ottenere l'approvazione del software.

Tuttavia, di solito si utilizza l'istruzione FOR in varie forme. Qualcuno ha creato un utile file batch che effettua una ricerca e sostituisce. Dai un'occhiata qui . È importante comprendere i limiti del file batch fornito. Per questo motivo non copio il codice sorgente in questa risposta.


4

Due file batch che forniscono search and replacefunzioni sono stati scritti dai membri Stack Overflow dbenhame aaciniutilizzati native built-in jscriptin Windows.

Sono entrambi robuste very swift with large filesconfrontati con semplici script batch, e anche simplerda utilizzare per la sostituzione di base del testo. Entrambi hanno una Windows regular expressioncorrispondenza del modello.

  1. Questo sed-likefile batch di supporto viene chiamato repl.bat(da dbenham).

    Esempio usando l' Linterruttore letterale:

    echo This is FOO here|repl "FOO" "BAR" L
    echo and with a file:
    type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
    
  2. Questo grep-likefile batch di supporto viene chiamatofindrepl.bat (da aacini).

    Esempio con espressioni regolari attive:

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

Entrambi diventano potenti utility a livello di sistema when placed in a folder that is on the path o possono essere utilizzati nella stessa cartella con un file batch o dal prompt cmd.

Entrambi hanno case-insensitiveinterruttori e anche molte altre funzioni.


3

Il comando Power shell funziona come un incantesimo

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

3

Ho appena affrontato un problema simile: "Cerca e sostituisci il testo nei file", ma con l'eccezione che sia per i nomi di file che per la ricerca / replica ho bisogno di usare regex. Poiché non ho familiarità con Powershell e voglio salvare le mie ricerche per un uso successivo, ho bisogno di qualcosa di più "user friendly" (preferibile se ha una GUI).

Quindi, mentre cercavo su Google :) ho trovato un ottimo strumento: FAR (Trova e sostituisci) (non FART).

Quel piccolo programma ha una bella interfaccia grafica e supporta regex per la ricerca nei nomi di file e nei file. L'unico svantaggio è che se si desidera salvare le impostazioni è necessario eseguire il programma come amministratore (almeno su Win7).


È la stessa risposta della risposta del 2010 @VonC In questa discussione
jeb

@jeb Ho sottolineato che FAR non è FART - due programmi diversi con nomi quasi identici. FAR ha una GUI e può funzionare con regex, mentre nei commenti sotto quel thread la gente dice che FART non supporta regex.
madcorp,

3

Sto preferisco usare sedda utilità GNU per Win32 , i seguenti hanno bisogno di essere notato

  • virgoletta singola ''non funziona in Windows, utilizzare ""invece
  • sed -inon funzionerà in Windows, avrà bisogno dello scambio di file

Quindi il codice di lavoro sedper trovare e sostituire il testo in un file in Windows è il seguente

sed -e "s/foo/bar/g" test.txt > tmp.txt && mv tmp.txt test.txt

2
Prima che gli utenti Windows eseguano immediatamente lo scambio di file: le versioni più recenti di sed supportano la modifica sul posto con -i! Se la tua versione sed funziona, controlla il comando da questa risposta: stackoverflow.com/a/33762001/2492801 .
Benjamin Bihler,

2

Questa è una cosa che gli script batch non funzionano bene.

Lo script collegato a morechilli funzionerà per alcuni file, ma sfortunatamente si strozzerà con quelli che contengono caratteri come pipe e e commerciali.

VBScript è uno strumento integrato migliore per questa attività. Consulta questo articolo per un esempio: http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx


2

@Rachel ha dato una risposta eccellente, ma qui c'è una variante per leggere il contenuto di una $datavariabile PowerShell . È quindi possibile modificare facilmente il contenuto più volte prima di scrivere su un file di output. Vedi anche come vengono dati i valori multilinea in un file 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%"

2

Usa powershell in .bat - per Windows 7+

la codifica utf8 è opzionale, buona per i siti 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"

1

Scarica Cygwin (gratuito) e utilizza comandi simili a unix dalla riga di comando di Windows.

La tua scommessa migliore: sed


10
Cygwin è malvagio. Non installarlo Meglio usare UnixUtils menzionato di seguito.
zedoo,

24
Cosa c'è di così male?
jm.

@jm Può essere perché devi installare il tutto insieme invece di usare un singolo eseguibile ogni volta che vuoi.
Andry,

Meglio usare PowerShell, in realtà è integrato in Windows.
Preza8

0

Puoi anche vedere gli strumenti Sostituisci e Sostituisci Filtro su https://zoomicon.github.io/tranXform/ (fonte inclusa). Il secondo è un filtro.

Lo strumento che sostituisce le stringhe nei file è in VBScript (per l'esecuzione nelle vecchie versioni di Windows è necessario Windows Script Host [WSH])

Il filtro probabilmente non funziona con Unicode a meno che non si ricompili con l'ultimo Delphi (o con FreePascal / Lazarus)


-5

Ho riscontrato questo problema più volte durante la codifica in Visual C ++. Se ce l'hai, puoi usare l'utilità Trova e Sostituisci di Visual Studio. Ti consente di selezionare una cartella e sostituire il contenuto di qualsiasi file in quella cartella con qualsiasi altro testo desiderato.

In Visual Studio: Modifica -> Trova e sostituisci Nella finestra di dialogo aperta, seleziona la cartella e compila le caselle "Trova cosa" e "Sostituisci con". Spero che questo possa essere utile.


2
Nadjib, la tua risposta non aiuta l'utente perché supponi che stiano utilizzando un software di cui non fanno menzione. Si prega di suggerire un'opzione che non richiede software.
Aibrean

@Aibrean la risposta è inutile, ma non per questo motivo, è il punto di ingresso che è sbagliato.
Paul
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.