¿Cómo se puede buscar y reemplazar texto en un archivo usando el entorno de línea de comandos de Windows?

StackOverflow https://stackoverflow.com/questions/60034

Pregunta

Estoy escribiendo un script de archivo por lotes utilizando el entorno de línea de comandos de Windows y quiero cambiar cada aparición de algún texto en un archivo (por ejemplo,"FOO") con otro (ej."BAR").¿Cuál es la forma más sencilla de hacerlo?¿Alguna función integrada?

¿Fue útil?

Solución

Muchas de las respuestas aquí me ayudaron a orientarme en la dirección correcta, sin embargo, ninguna era adecuada para mí, así que publico mi solución.

Tengo Windows 7, que viene con PowerShell integrado.Aquí está el script que utilicé para buscar/reemplazar todas las instancias de texto en un archivo:

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

Para explicarlo:

  • powershell inicia powershell.exe, que está incluido en Windows 7
  • -Command "... " es un argumento de línea de comando para powershell.exe que contiene el comando para ejecutar
  • (gc myFile.txt) lee el contenido de myFile.txt (gc es corto para el Get-Content dominio)
  • -replace 'foo', 'bar' simplemente ejecuta el comando reemplazar para reemplazar foo con bar
  • | Out-File myFile.txt canaliza la salida al archivo myFile.txt

Powershell.exe ya debería ser parte de su declaración PATH, pero si no, puede agregarlo.La ubicación en mi máquina es C:\WINDOWS\system32\WindowsPowerShell\v1.0

Otros consejos

Si tiene una versión de Windows que admite .Net 2.0, reemplazaría su shell. Potencia Shell le brinda todo el poder de .Net desde la línea de comando.También hay muchos comandos integrados.El siguiente ejemplo resolverá su pregunta.Estoy usando los nombres completos de los comandos, hay alias más cortos, pero esto le da algo a Google.

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

Recién usado PEDO ("F Indiana A Dakota del Norte R reemplazar t ext" utilidad de línea de comando):
Excelente pequeño programa gratuito para reemplazar texto dentro de un gran conjunto de archivos.

Los archivos de configuración están en SourceForge.

Ejemplo de uso:

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

Previsualizará los reemplazos a realizar de forma recursiva en los archivos de esta distribución de Perl.

El único problema:el icono del sitio web de FART no es precisamente de buen gusto, refinado o elegante;)


Actualización 2017 (7 años después) jagb Señala en los comentarios al artículo de 2011 "Tirarse pedos de forma sencilla: buscar y reemplazar texto" de Mikail Tunç

Reemplace: reemplace una subcadena con la descripción de sustitución de cadenas:Para reemplazar una subcadena con otra cadena, utilice la función de sustitución de cadenas.El ejemplo que se muestra aquí reemplaza todas las apariciones de errores ortográficos "teh" con "the" en la variable de cadena str.

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

Salida del guión:

teh cat in teh hat
the cat in the hat

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

Crear archivo reemplazar.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

Para usar este script revisado (al que llamaremos reemplazar.vbs), simplemente escriba un comando similar a este desde el símbolo del sistema:

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

BatchSubstitute.bat en dostips.com es un ejemplo de búsqueda y reemplazo utilizando un archivo por lotes puro.

Utiliza una combinación de FOR, FIND y CALL SET.

Líneas que contienen caracteres entre "&<>]|^ puede ser tratado incorrectamente.


Nota - Asegúrese de ver la actualización al final de esta respuesta para obtener un enlace al JREPL.BAT superior que reemplaza a REPL.BAT
JREPL.BAT 7.0 y superior admite de forma nativa Unicode (UTF-16LE) a través de /UTF opción, así como cualquier otro conjunto de caracteres, incluido UTF-8, a través de ADO!!!!


He escrito una pequeña utilidad híbrida JScript/batch llamada REPL.BAT eso es muy conveniente para modificar archivos ASCII (o ASCII extendido) a través de la línea de comando o un archivo por lotes.El script puramente nativo no requiere la instalación de ningún ejecutable de terceros y funciona en cualquier versión moderna de Windows desde XP en adelante.También es muy rápido, especialmente en comparación con soluciones puramente discontinuas.

REPL.BAT simplemente lee la entrada estándar, realiza una búsqueda y reemplazo de expresiones regulares JScript y escribe el resultado en la salida estándar.

Aquí hay un ejemplo trivial de cómo reemplazar foo con bar en test.txt, asumiendo que REPL.BAT está en su carpeta actual, o mejor aún, en algún lugar dentro de su RUTA:

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

Las capacidades de expresiones regulares de JScript lo hacen muy poderoso, especialmente la capacidad del texto de reemplazo para hacer referencia a subcadenas capturadas del texto de búsqueda.

He incluido una serie de opciones en la utilidad que la hacen bastante poderosa.Por ejemplo, combinando el M y X ¡Las opciones permiten la modificación de archivos binarios!El M La opción de varias líneas permite realizar búsquedas en varias líneas.El X La opción de patrón de sustitución extendida proporciona secuencias de escape que permiten la inclusión de cualquier valor binario en el texto de reemplazo.

Toda la utilidad podría haberse escrito como JScript puro, pero el archivo por lotes híbrido elimina la necesidad de especificar explícitamente CSCRIPT cada vez que desee utilizar la utilidad.

Aquí está el script REPL.BAT.La documentación completa está integrada en el 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));
}


ACTUALIZACIÓN IMPORTANTE

Dejé de desarrollar REPL.BAT y lo reemplacé con JREPL.BAT.Esta nueva utilidad tiene la misma funcionalidad que REPL.BAT y mucho más:

  • Compatibilidad con Unicode UTF-16LE a través de capacidades Unicode CSCRIPT nativas y cualquier otro conjunto de caracteres (incluido UTF-8) a través de ADO.
  • Leer directamente desde/escribir directamente en un archivo:no hay necesidad de tuberías, redireccionamiento o comando de movimiento.
  • Incorporar JScript proporcionado por el usuario
  • Instalación de traducción similar a Unix tr, solo que también admite búsqueda de expresiones regulares y reemplazo de JScript.
  • Descartar texto que no coincida
  • Prefijar líneas de salida con número de línea
  • y más...

Como siempre, la documentación completa está incluida en el script.

La solución trivial original ahora es aún más sencilla:

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

La versión actual de JREPL.BAT está disponible en DosTips.Lea todas las publicaciones posteriores en el hilo para ver ejemplos de uso y una historia del desarrollo.

Usar FNR

Utilizar el fnr utilidad.Tiene algunas ventajas sobre fart:

  • Expresiones regulares
  • GUI opcional.Tiene un "botón Generar línea de comando" para crear texto de línea de comando para colocarlo en un archivo por lotes.
  • Patrones de varias líneas:La GUI le permite trabajar fácilmente con patrones de varias líneas.En FART tendrías que escapar manualmente de los saltos de línea.
  • Le permite seleccionar la codificación del archivo de texto.También tiene una opción de detección automática.

Descarga FNR aquí: http://findandreplace.io/?z=codeplex

Ejemplo de uso:fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"

No creo que haya una manera de hacerlo con ningún comando integrado.Te sugiero que descargues algo como Gnuwin32 o UnxUtils y usar el sed comando (o descargar solo sed):

sed -c s/FOO/BAR/g filename

Sé que llego tarde a la fiesta...

Personalmente, me gusta la solución en:- http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

También utilizamos ampliamente la función de deduplicación para ayudarnos a entregar aproximadamente 500 correos electrónicos diarios a través de SMTP desde:- https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

y ambos funcionan de forma nativa sin necesidad de herramientas ni utilidades adicionales.

REEMPLAZO:

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

DESDUPLICADOR (tenga en cuenta el uso de -9 para un número 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

¡Gracias!

Cuando trabajas con Git en Windows entonces simplemente enciende git-bash y use sed.O, cuando use Windows 10, inicie "Bash en Ubuntu en Windows" (desde el subsistema de Linux) y use sed.

Es un editor de secuencias, pero puede editar archivos directamente usando el siguiente comando:

sed -i -e 's/foo/bar/g' filename
  • -i La opción se utiliza para editar en el lugar del nombre del archivo.
  • -e La opción indica un comando para ejecutar.
    • s se utiliza para reemplazar la expresión encontrada "foo" con "bar" y g se utiliza para reemplazar cualquier coincidencia encontrada.

Nota de ereOn:

Si desea reemplazar una cadena en archivos versionados únicamente de un repositorio Git, puede utilizar:

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

lo cual hace maravillas.

He usado Perl y funciona de maravilla.

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

.orig es la extensión que agregaría al archivo original

Para varios archivos coincidentes, como *.html

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

Jugué con algunas de las respuestas existentes aquí y prefiero mi solución mejorada...

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

o si desea guardar el resultado nuevamente en un archivo...

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

El beneficio de esto es que puede canalizar la salida de cualquier programa.También consideraremos el uso de expresiones regulares con esto.Sin embargo, no pude encontrar la manera de convertirlo en un archivo BAT para facilitar su uso...:-(

Con el sustituto.bat

1) con e? opción que evaluará secuencias de caracteres especiales como \n\r y secuencias Unicode.En este caso sustituirá al citado. "Foo" y "Bar":

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

2) Reemplazo sencillo donde el Foo y Bar no se citan.

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

Aquí hay una solución que encontré que funcionó en Win XP.En mi archivo por lotes en ejecución, incluí lo siguiente:

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

El replace.bat El archivo es el siguiente.No encontré una manera de incluir esa función dentro del mismo archivo por lotes, porque el %%a La variable siempre parece dar el último valor en el bucle 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

Echa un vistazo a ¿Existe alguna utilidad tipo sed para cmd.exe? que solicitó un sed equivalente en Windows, también debería aplicarse a esta pregunta.Resumen ejecutivo:

  • Se puede hacer en un archivo por lotes, pero no es bonito.
  • Hay muchos ejecutables de terceros disponibles que lo harán por usted, si tiene el lujo de instalar o simplemente copiar un archivo ejecutable.
  • Se puede hacer con VBScript o similar si necesita algo que pueda ejecutarse en Windows sin modificaciones, etc.

Puede que sea un poco tarde, pero frecuentemente busco cosas similares, ya que no quiero pasar por la molestia de obtener la aprobación del software.

Sin embargo, normalmente se utiliza la declaración FOR de varias formas.Alguien creó un archivo por lotes útil que busca y reemplaza.Echar un vistazo aquí.Es importante comprender las limitaciones del archivo por lotes proporcionado.Por esta razón no copio el código fuente en esta respuesta.

Dos archivos por lotes que suministran search and replace Las funciones han sido escritas por miembros de Stack Overflow. dbenham y aacini usando native built-in jscript en Windows.

Ellos dos robust y very swift with large files en comparación con secuencias de comandos por lotes simples, y también simpler para usar para el reemplazo básico de texto.Ambos tienen Windows regular expression la coincidencia de patrones.

  1. Estesed-like El archivo por lotes auxiliar se llama repl.bat (por dbenham).

    Ejemplo usando el L cambio literal:

    echo This is FOO here|repl "FOO" "BAR" L
    echo and with a file:
    type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
    
  2. Este grep-like El archivo por lotes auxiliar se llama findrepl.bat (por aacini).

    Ejemplo que tiene expresiones regulares activas:

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

Ambos se convierten en potentes utilidades para todo el sistema. when placed in a folder that is on the path, o se puede usar en la misma carpeta con un archivo por lotes, o desde el indicador cmd.

Ambos tienen case-insensitive interruptores y también muchas otras funciones.

El comando Power Shell funciona de maravilla

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

Acabo de enfrentar un problema similar: "Buscar y reemplazar texto dentro de archivos", pero con la excepción de que tanto para los nombres de archivos como para buscar/reemplazar necesito usar expresiones regulares.Como no estoy familiarizado con Powershell y quiero guardar mis búsquedas para usarlas más adelante, necesito algo más "fácil de usar" (preferible si tiene GUI).

Entonces, mientras buscaba en Google :) encontré una gran herramienta: FAR (Buscar y reemplazar) (no PEDO).

Ese pequeño programa tiene una buena GUI y admite expresiones regulares para buscar nombres de archivos y dentro de archivos.La única desventaja es que si desea guardar su configuración, debe ejecutar el programa como administrador (al menos en Win7).

Esto es algo que los scripts por lotes simplemente no hacen bien.

La secuencia de comandos más chile vinculado funcionará para algunos archivos, pero desafortunadamente se ahogará en aquellos que contengan caracteres como barras verticales y ampersands.

VBScript es una mejor herramienta integrada para esta tarea.Vea este artículo para ver un ejemplo:http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx

@Rachel dio una excelente respuesta, pero aquí hay una variación para leer contenido en un PowerShell. $data variable.Luego podrá manipular fácilmente el contenido varias veces antes de escribirlo en un archivo de salida.Vea también cómo se proporcionan valores de varias líneas en archivos por lotes .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%"

Utilice powershell en .bat - para Windows 7+

La codificación utf8 es opcional, buena para sitios 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"

prefiero usar sed de Utilidades GNU para Win32, es necesario tener en cuenta lo siguiente

  • una frase '' no funcionará en Windows, use "" en cambio
  • sed -i no funcionará en Windows, necesitará un archivo intercambiando

Entonces el código de trabajo de sed para buscar y reemplazar texto en un archivo en Windows es el siguiente

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

Descargar Cygwin (gratis) y utilice comandos similares a Unix en la línea de comandos de Windows.

Su mejor apuesta:sed

También puede ver las herramientas Reemplazar y Reemplazar filtro en https://zoomicon.github.io/tranXform/ (fuente incluida).El segundo es un filtro.

La herramienta que reemplaza cadenas en archivos está en VBScript (necesita Windows Script Host [WSH] para ejecutarse en versiones antiguas de Windows)

El filtro probablemente no funcione con Unicode a menos que vuelva a compilar con la última versión de Delphi (o con FreePascal/Lazarus)

Me he enfrentado a este problema varias veces mientras codificaba en Visual C++.Si lo tiene, puede utilizar la utilidad Buscar y reemplazar de Visual Studio.Le permite seleccionar una carpeta y reemplazar el contenido de cualquier archivo en esa carpeta con cualquier otro texto que desee.

En Visual Studio:Editar -> Buscar y reemplazar en el cuadro de diálogo abierto, seleccione su carpeta y complete los cuadros "Buscar qué" y "Reemplazar con".Esperamos que esto sea útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top