Windows cmd replace string in file

I am writing a batch file script using Windows command-line environment and want to change each occurrence of some text in a file (ex. "FOO") with another (ex. "BAR"). What is the simplest way to d...

Note — Be sure to see the update at the end of this answer for a link to the superior JREPL.BAT that supersedes REPL.BAT
JREPL.BAT 7.0 and above natively supports unicode (UTF-16LE) via the /UTF option, as well as any other character set, including UTF-8, via ADO!!!!


I have written a small hybrid JScript/batch utility called REPL.BAT that is very convenient for modifying ASCII (or extended ASCII) files via the command line or a batch file. The purely native script does not require installation of any 3rd party executeable, and it works on any modern Windows version from XP onward. It is also very fast, especially when compared to pure batch solutions.

REPL.BAT simply reads stdin, performs a JScript regex search and replace, and writes the result to stdout.

Here is a trivial example of how to replace foo with bar in test.txt, assuming REPL.BAT is in your current folder, or better yet, somewhere within your PATH:

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

The JScript regex capabilities make it very powerful, especially the ability of the replacement text to reference captured substrings from the search text.

I’ve included a number of options in the utility that make it quite powerful. For example, combining the M and X options enable modification of binary files! The M Multi-line option allows searches across multiple lines. The X eXtended substitution pattern option provides escape sequences that enable inclusion of any binary value in the replacement text.

The entire utility could have been written as pure JScript, but the hybrid batch file eliminates the need to explicitly specify CSCRIPT every time you want to use the utility.

Here is the REPL.BAT script. Full documentation is embedded within the 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));
}

IMPORTANT UPDATE

I have ceased development of REPL.BAT, and replaced it with JREPL.BAT. This newer utility has all the same functionality of REPL.BAT, plus much more:

  • Unicode UTF-16LE support via native CSCRIPT unicode capabilities, and any other character set (including UTF-8) via ADO.
  • Read directly from / write directly to a file: no need for pipes, redirection, or move command.
  • Incorporate user supplied JScript
  • Translation facility similar to unix tr, only it also supports regex search and JScript replace
  • Discard non-matching text
  • Prefix output lines with line number
  • and more…

As always, full documentation is embedded within the script.

The original trivial solution is now even simpler:

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

The current version of JREPL.BAT is available at DosTips. Read all of the subsequent posts in the thread to see examples of usage and a history of the development.

SET string=bath Abath Bbath XYZbathABC
SET modified=%string:bath=hello%
ECHO %string%
ECHO %modified%

EDIT

Didn’t see at first that you wanted the replacement to be preceded by reading the string from a file.

Well, with a batch file you don’t have much facility of working on files. In this particular case, you’d have to read a line, perform the replacement, then output the modified line, and then… What then? If you need to replace all the ocurrences of ‘bath’ in all the file, then you’ll have to use a loop:

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

You can add a redirection to a file:

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

Or you can apply the redirection to the batch file. It must be a different file.

EDIT 2

Added proper toggling of delayed expansion for correct processing of some characters that have special meaning with batch script syntax, like !, ^ et al. (Thanks, jeb!)

POWERSHELL

Example PowerShell syntax below for find and replacement of strings within a specific file.

EXAMPLE

(Get-Content "C:UsersuserDesktoptesttestzzz.txt") | 
Foreach-Object {$_.replace("\changeme", "\servershare name")} | 
Set-Content "C:UsersuserDesktoptesttestzzz.txt"

Resources:

  • http://ss64.com/ps/replace.html
  • http://blogs.technet.com/b/heyscriptingguy/archive/2008/01/17/how-can-i-use-windows-powershell-to-replace-characters-in-a-text-file.aspx

F.A.R.T

For the F.A.R.T issue with spaces specifically, I think you just need to add double-quotes around the strings you’re passing to it. Give that a shot and then perhaps you can just continue to keep using it without further change.

EXAMPLE

"%~dp0Softwarefart" -i -r "%~dp0Softwareconfig.cfg" "\changeme" "%N%"

You can also add the capital -V switch (see below example) to get verbose detail of the error message if needed to troubleshoot further, but I’ve resolved this issue with F.A.R.T and a space in a replacement string by adding the double-quotes around it as in my below example #2.

Example #2

fart -i -C -V "C:UsersuserDesktoptesttestzzz.txt" "\changeme" "\servershare name"

You also may want to consider excluding the -r option if you’re only changing the text in a SINGLE file (i.e. config.cfg). Below is the FART /? options I see exaplaining the options.

Usage: FART [options] [--] <wildcard>[,...] [find_string] [replace_string]

Options:
 -h, --help          Show this help message (ignores other options)
 -q, --quiet         Suppress output to stdio / stderr
 -V, --verbose       Show more information
 -r, --recursive     Process sub-folders recursively
 -c, --count         Only show filenames, match counts and totals
 -i, --ignore-case   Case insensitive text comparison
 -v, --invert        Print lines NOT containing the find string
 -n, --line-number   Print line number before each line (1-based)
 -w, --word          Match whole word (uses C syntax, like grep)
 -f, --filename      Find (and replace) filename instead of contents
 -B, --binary        Also search (and replace) in binary files (CAUTION)
 -C, --c-style       Allow C-style extended characters (xFFtnr\ etc.)
     --cvs           Skip cvs dirs; execute "cvs edit" before changing files
     --svn           Skip svn dirs
     --remove        Remove all occurences of the find_string
 -a, --adapt         Adapt the case of replace_string to found string
 -b, --backup        Make a backup of each changed file
 -p, --preview       Do not change the files but print the changes

Topic: How to search & replace a string in text file using a batch file  (Read 77024 times)

0 Members and 1 Guest are viewing this topic.

H4ckRn00b

I want to write a batch file which can look through a textfile and find a string and replace it with another string.
This two string will not be variables. They will be permantly the same.

Conceptually, it should do something like this

  • Open file FRUIT.TXT
    Find string APPLE
    Replace with PEAR
    Repeat this till end of the file
    Save FRUIT.TXT

Thanks!


Logged


DaveLembke

Is this a homework assignment?

There is a method that was shared by Foxidrive that helped me with a replacement within text files but it was achieved by QBasic on an old Windows NT system, and not pure batch. More info at the link here if QBasic is an option.

https://www.computerhope.com/forum/index.php?topic=151160.30


Logged


nil

this answer from stackoverflow worked for me.

https://stackoverflow.com/questions/2772456/string-replacement-in-batch-file/2772498

for example

C:Usersnilnewfruit>type FRUIT.TXT
APPLES ARE GOOD FOR YOU.
I WANT TO EAT AN APPLE.

C:Usersnilnewfruit>type 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
objFile.Close

C:Usersnilnewfruit>cscript replace.vbs «FRUIT.TXT» «APPLE» «PEAR»
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.

C:Usersnilnewfruit>type FRUIT.TXT
PEARS ARE GOOD FOR YOU.
I WANT TO EAT AN PEAR.


Logged

Do not communicate by sharing memory; instead, share memory by communicating.

—Effective Go


H4ckRn00b

Is this a homework assignment?

Wow, such insults! i should reply with a biting comment….. about projection-projection-projection or something, but in order to de-escalate, I won’t.

I can see you’ve been infected by the arrogance-*censored*-baseless-suspicion virus that’s so virulent on stackedOverflow. Don’t let it spread to others.

And Qbasic???? Please ………….


Logged


Geek-9pm

Q basic is free and compatible with recent versions of Windows.
In QBasic you would read the text into an array and then go through the array and find and replace strings. Rather starlight standard stuff people used to do years ago.
 forward.

An there are other methods available. There are programs  do find and replace  inside a batch file Among these are things ported from UNIX  to Windows.


Logged


BC_Programmer

Dave asked if it was homework primarily because it was phrased much like a homework assignment. It’s hardly an «insult», but it’s useful to know because then answers can be catered to that. For homework, than the aim was to learn something. Being given a working solution won’t help you if the same topic comes up later. Conversely, if the solution is needed for the task it performs, than it would simply be more important to have the «solution» — a working batch script- as learning is more «secondary» in that scenario.

As to the problem.

You can iterate through all the lines in a file using an appropriate «for /F» command.

setlocal enabledelayedexpansion
for /F "tokens=*" %%A in (fruit.txt) do (
echo %%A
)

You can use command prompt to replace text within an environment variable via set:

set line=%%A
set result=%line:APPLE=PEAR%

You can use >> and > to redirect echoed output to a file. With this problem I’d suggest a temporary output file, and after the for command finishes, erasing the original file and renaming the temporary file to the original name.

From what I can tell, the replacement feature of «set» doesn’t seem to work if the find or replacement text has spaces- not an issue here since APPLE and PEAR would be hard-coded as per the description, but worth considering if this will be expanded in some way.


Logged

I was trying to dereference Null Pointers before it was cool.


Allan

The only biting comments I see here are in your second post. You are new here and asking for assistance. You’ve received intelligent and helpful responses from some of our most respected members. I don’t know what you are used to based on your experiences at other forums, but on this site we are here to offer help. Please accept that help with the same courtesy and respect with which it is offered.


Logged


nil

The VBScript solution works for every version of Windows, without installing any software. I’ll document it on the site.


Logged

Do not communicate by sharing memory; instead, share memory by communicating.

—Effective Go


Salmon Trout

You can use command prompt to replace text within an environment variable via set:set line=%%A
set result=%line:APPLE=PEAR%

if  the variable line is assigned the value of a FOR metavariable, we’re in a bracket block, and don’t we need delayed expansion?

« Last Edit: November 18, 2019, 10:10:09 AM by Salmon Trout »


Logged


Salmon Trout

From what I can tell, the replacement feature of «set» doesn’t seem to work if the find or replacement text has spaces- not an issue here since APPLE and PEAR would be hard-coded as per the description, but worth considering if this will be expanded in some way.


C:UsersMike>set string1=Mary had a little lamb

C:UsersMike>echo %string1%
Mary had a little lamb

C:UsersMike>set string2=%string1:Mary=Peter%

C:UsersMike>echo %string2%
Peter had a little lamb

C:UsersMike>set string3=%string1:Mary had=Peter wanted%

C:UsersMike>echo %string3%
Peter wanted a little lamb

C:UsersMike>set string4=%string1:Mary=Peter, Paul and Mary%

C:UsersMike>echo %string4%
Peter, Paul and Mary had a little lamb

C:UsersMike>set string5=%string1:Mary=Peter, Paul and Mary% && set string5=%string5:lamb=lamb each%

C:UsersMike>echo %string5%
Peter, Paul and Mary had a little lamb each

Now you all know my name….

« Last Edit: November 18, 2019, 10:18:33 AM by Salmon Trout »


Logged


H4ckRn00b

for example

I’ve customized/changed that script somewhat, into:

Const ForReading = 1
Const ForWriting = 2
Const FileIn = "FRUIT.TXT"
Const FileOut = "FRUIT.TXT"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(FileIn, ForReading)

strText = objFile.ReadAll
objFile.Close

strNewText = Replace(strText, "OrangesApples", "LemonPears")
strNewText = Replace(strText, "Apples", "Pears")

Set objFile = objFSO.OpenTextFile(FileOut, ForWriting)
objFile.WriteLine strNewText
objFile.Close

[/tt]

Question 1: I’ve tried to make this script run at start up, with a batch file in the Startup folder, but somehow that doesn’t work, it’s only running if I execute it manually. How do I make it run a start up, for both Win7 and Win10?
The first replacment line with «OrangesApples» and «LemonPears»  occurs just once at the beginning of the file, the 2nd replacment line with «Apples» and «Pears» occurs more frequently. And yes, it’s a subset of the first line.

Question 2: Your script is more complicated and/or longer. Why is that, what does it do different than the above script?


Logged


Salmon Trout

I can see you’ve been infected by the arrogance-*censored*-baseless-suspicion virus that’s so virulent on stackedOverflow. Don’t let it spread to others.

I find with the various Stack Exchange sites I belong to, that you tend to get back roughly what you put in.


Logged


H4ckRn00b

I find with the various Stack Exchange sites I belong to, that you tend to get back roughly what you put in.

Well, not my experience. How’s that ad line again? «YMMV».


Logged


Salmon Trout

That VBScript has a feature I don’t like. It overwrites the input file. It’s a bit late to find out it doesn’t do what you want if you have obliterated your original data. At least it doesn’t have lots of set [whatever]=Nothing lines at the end.

Where did that script come from?

As for Question 1, you can place a one-line batch script in your Startup folder

cscript //nologo path/to/scriptname.vbs

Change cscript to wscript if you don’t want a console window.

If you code the actual paths to the input and output .txt files in the script, you can put the .vbs script itself in the Startup folder.

This all looks a bit shaky though. If this is corporate data in a work setting, should you be doing this?


Logged


H4ckRn00b


C:UsersMike>set string5=%string1:Mary=Peter, Paul and Mary% && set string5=%string5:lamb=lamb each%

C:UsersMike>echo %string5%
Peter, Paul and Mary had a little lamb each

While the gist of this last set command example is clear to me: (In one string, two parts are replaced), the details aren’t so clear:
Does it mean: In string1, replace ‘Mary‘ with ‘Peter, Paul and Mary‘ and then put that in string 5, and then, in the resulting string 5, replace ‘lamb‘ with ‘lamb each‘? And what is the function of the double ampersand? concatenation, or something else?


Logged


  • Remove From My Forums
  • Question

  • I am writing a batch script to replace » «, with » «. The below code works but it prefixes each line with the line number and :.

    It is the last part of the line that I am trying to replace.

    E.g.

    "                    ","BALANCE_SHEET       ","ASSETS              ","03","LEVEL_2   ",Asset Accounts,"                              ",

    To be replaced as

    "                    ","BALANCE_SHEET       ","ASSETS              ","03","LEVEL_2   ",Asset Accounts,"                              "

    Code:

    @echo off &setlocal
    set "search="                              ","
    set "replace="                              ""
    set "textfile=Build_Accounts_Plan_Source.txt"
    set "newfile=Build_Accounts_Plan_Source_new.txt"
    
    (for /f "delims=" %%i in ('findstr /n "^" "%textfile%"') do (
        set "line=%%i"
        setlocal enabledelayedexpansion
        set "line=!line:%search%=%replace%!"
        echo(!line!
        endlocal
    ))>"%newfile%"
    type "%newfile%"

    Output:

    3:"                    ","BALANCE_SHEET       ","ASSETS              ","03","LEVEL_2   ",Asset Accounts,"                              "

    Regards,

    Ragav.

Answers

  • Did you retype the code or did you use copy/paste? Retyping is not a good idea.

    You can do this to find the cause of the problem:

    1. Run the modified code below.
    2. Use notepad.exe to open the file TempVBS.vbs in your %temp% folder.
    3. Mark & copy the code, then paste it into your reply.

    @echo off
    set «textfile=Build_Accounts_Plan_Source.txt»
    set «newfile=Build_Accounts_Plan_Source_new.txt»
    set Scr=»%temp%TempVBS.vbs»
    (  echo Set oFSO = CreateObject(«Scripting.FileSystemObject»^)
       echo Set oInput = oFSO.OpenTextFile(WScript.Arguments(0^), 1^)
       echo sData = Replace(oInput.ReadAll, «,» ^& VbCrLf, VbCrLf^)
       echo Set oOutput = oFSO.CreateTextFile(WScript.Arguments(1^), True^)
       echo oOutput.Write sData
       echo oInput.Close
       echo oOutput.Close) > %Scr%
    cscript //nologo %Scr% %textfile% %newfile%

    • Marked as answer by

      Wednesday, February 12, 2014 12:37 AM

  • Files that start with

    @echo off

    are BATCH files, not VBScript files! You must save the code with a .bat extension.

    • Marked as answer by
      Ragavhere
      Wednesday, February 12, 2014 12:37 AM

Задача замены строки или её части в текстовом файле в командной строке или в bat файле может быть решена различными способами, в зависимости от требований.

Варианты замены текста из командной строки

Утилита поиска и замены текста

Специализированный инструмент всегда даёт самый функциональный и быстрый для реализации способ: готовые утилиты поддерживают все кодировки файлов, имеют опции для разных вариантов замены, поддерживают регулярные выражения и не требуют отладки!

Единственная ситуация, когда вариант с готовой утилитой может не подойти – если есть непреодолимое требование не использовать нестандартные (не входящие в состав Windows) компоненты при развёртывании на большое число корпоративных компьютеров. Но такое встречается нечасто.

Поэтому применение готового, отлаженного и протестированного инструмента является предпочтительным вариантом!

Скрипт на JS или VBS

Возможности VBScript/JScript позволяют реализовать различные варианты замены, включая поддержку регулярных выражений, но всё-таки имеют ограниченные возможности: поддержку меньшего числа кодировок файлов, отсутствие массовой замены, отсутствие подкаталогов и т.д. Любое изменение необходимо отлаживать и тестировать. В общем, очередной «велосипед».

Вариант со скриптом оптимально использовать в случае, когда по каким-то причинам нельзя использовать готовую утилиту.

Bat файлы

О серьёзных возможностях программирования bat файлов говорить не приходится – собственно, bat файл потому и называется пакетным файлом, что предназначен для запуска списка команд по очереди, а не для программирования циклов и обработки переменных.

Сильные стороны bat файлов – удобная форма запуска команд по списку, простое перенаправление вывода и использование переменных окружения, но лучше в bat файлах не программировать.

Ладно раньше, когда предустановленной альтернативы не было, но сейчас, когда на всех компьютерах есть WSH с VBScript/JScript и PowerShell…

Замена текста в файле скриптом JScript

Чтобы сделать замену текста в текстовом файле, в том числе, с использованием регулярных выражений, можно использовать следующий скрипт JScript, который:

  • открывает указанный текстовый файл
  • читает его построчно
  • для каждой строки выполняет замену по регулярному выражению

Код скрипта замены текста

// Имя файла, искомый текст и текст замены берём из аргументов
var file_name = WScript.Arguments(0);
var text_sample = WScript.Arguments(1);
var text_replace = WScript.Arguments(2);

var fso=WScript.CreateObject("Scripting.FileSystemObject");
// Переносим исходный файл во временный
var file_name_tmp = file_name+".tmp";
if (fso.FileExists(file_name_tmp))
    fso.DeleteFile(file_name_tmp);
fso.MoveFile(file_name,file_name_tmp);

var fo = fso.OpenTextFile(file_name_tmp,1,false,false);
var fr = fso.OpenTextFile(file_name,2,true,false);

// Выполняем замену текста, с построчной обработкой
var re=new RegExp(text_sample);

while (!fo.AtEndOfStream) {
    var line = fo.ReadLine();
    var line_replace = line.replace(re,text_replace);
    fr.WriteLine(line_replace);
}
fo.Close();
fr.Close();
// Удаляем временный файл
fso.DeleteFile(file_name_tmp);

Запуск скрипта замены текста

При запуске скрипта необходимо параметрами передать имя файла, строку поиска (регулярное выражение), строку замены:

cscript //nologo replace_text.js content.txt Foo Bar

Примечания к скрипту

Скрипт обрабатывает файлы в ANSI кодировке. Для Unicode файла необходимо заменить 4-й аргумент в вызовах OpenTextFile c false на true.

Поскольку обработка ведётся по строкам, то регулярные выражения сработают только в пределах одной строки.

Примеры использования скрипта replace-text-script-samples.zip

Замена текста программой nhrt

Больше возможностей и гибкости: поддержка всех кодировок файлов с автоматическим определением, пакетная обработка и многое другое в программе nhrt.

Здравствуйте. Сабж. Надо заменить 13ю строку в файле на заранее известную. Пишу так

for /f «skip=12» in (settings.ini) do (echo dparm=BIND=0,lck=’ru’,APP=’GPS’,HST=’%COMPUTERNAME%’)

По задумке должно пропустить 12 строк с начала файла и заменить на то, что указано в скобках. По факту — ноль реакции. Возможно, надо еще прервать цикл, т.к. замена производится один раз, но не уверен, это предположение, раньше с смд дел не имел.


  • Вопрос задан

    более трёх лет назад

  • 6081 просмотр

В общем, полазил еще по форумам и сделал. Изначально задача была заменить в файле кусок именем компьютера, на котором запущен файл. Но я намудрил, решил заменить целую строчку, поэтому долго возился. Все оказалось прозаичнее. В примере ниже pc-name — это кусок, подлежащий замене на имя компа, получаемое через %computername%.

@echo off
setlocal enabledelayedexpansion
Set infile=settings.ini
Set find=pc-name
Set replace=%COMPUTERNAME%
@echo off
setlocal enabledelayedexpansion
set COUNT=0
for /F «tokens=* delims=, eol=#» %%n in (!infile!) do (
set LINE=%%n
set TMPR=!LINE:%find%=%replace%!
Echo !TMPR!>>TMP.TXT
)
move TMP.TXT %infile%

Пригласить эксперта

Контент в 12-й строке известен?

как вариант

Можно PowerShell

$FilePath = C:path_to_settings.ini
(Get-Content $FilePath) -replace 'parametr =.*','parametr = "YOUR TEXT"' | Out-File $FilePath

На PowerShell делается просто
Запустить PoSH из скрипта в командной строке : (содержимое bat файла)

powershell "$f=(Get-Content вашфайлик);$f[номерстроки]='новыйконтент';$f | set-content вашфайлик"

И никто не заставляет писать монструозные конструкции, правда? :)


  • Показать ещё
    Загружается…

05 февр. 2023, в 11:27

15000 руб./за проект

05 февр. 2023, в 11:25

4000 руб./за проект

05 февр. 2023, в 11:16

500 руб./в час

Минуточку внимания

  1. Use Batch Script To Replace Text From the File
  2. Use Windows PowerShell To Replace Text From the File

Replace Text From File in Batch Script

In this article, we will introduce some methods through which you can replace texts in a file. We are going to see two different ways.

Our first method contains only the batch script to perform the task and the second method provides the solution by Windows PowerShell.

Suppose we have a text file with the content below.

Test.txt:

This is text that is saved in a text file. This is an update. ,,,,,,,,,,,,

We are going to replace these commands with empty characters.

Use Batch Script To Replace Text From the File

Batch Script:

@echo off
FOR /f "tokens=*" %%s IN (Test.txt) DO (
  SET Texts=%%s
)
set Texts=%Texts:,=%

FOR /F "tokens=* delims=" %%x IN (Test.txt) DO SET text=%%x
ECHO %Texts% > "G:BATCHTest.txt" :: the path location of the txt file

We first read the file using the line FOR /f "tokens=*" %%s IN (Test.txt) DO ( and then through the line SET Texts=%%s, we initialize a string variable with the texts of the file. We replaced each comma with an empty character through the line set Texts=%Texts:,=%.

Lastly, we put the text into the file again. When we run the code above, we will see changes in our file content below.

This is text that is saved in a text file. This is an update.

Use Windows PowerShell To Replace Text From the File

This method will also provide the same result as our previous method did. In this method, we used PowerShell in our batch script. The example code for this method will look like this,

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

When we run the code, we’ll see changes in our file content below.

This is text that is saved in a text file. This is an update.

Remember that the commands we discussed here are only for the Windows command prompt or CMD environment.

Like this post? Please share to your friends:
  • Windows cmd remove directory with files
  • Windows cannot complete the extraction что это
  • Windows cannot complete installation in safe mode
  • Windows cannot communicate with the device or resource primary dns server
  • Windows cannot be installed to this disk this computer s