87

Can anyone tell me using batch file in windows ...how to read from a file and replace string=bath from file containing=bath Abath Bbath XYZbathABC with string hello so that the output is like hello Ahello Bhello XYZhelloABC

7 Answers 7

112

Expanding from Andriy M, and yes you can do this from a file, even one with multiple lines

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=test.txt"
set "OUTTEXTFILE=test_out.txt"
set "SEARCHTEXT=bath"
set "REPLACETEXT=hello"

for /f "delims=" %%A in ('type "%INTEXTFILE%"') do (
    set "string=%%A"
    set "modified=!string:%SEARCHTEXT%=%REPLACETEXT%!"
    echo !modified!>>"%OUTTEXTFILE%"
)

del "%INTEXTFILE%"
rename "%OUTTEXTFILE%" "%INTEXTFILE%"
endlocal

EDIT

Thanks David Nelson, I have updated the script so it doesn't have the hard coded values anymore.

Sign up to request clarification or add additional context in comments.

4 Comments

its nice and it works, but it does strip out blank lines for some reason. Gonzalezea's answer at the following link fixes the blank line stripping issue: stackoverflow.com/a/20227248/280109
Some information for readers thinking about using the code: FOR ignores empty lines and with this code also lines starting with ; because of being the default for option eol. Lines with one or more ! are not processed correct with this code because of enabled delayed expansion required by this code. ECHO outputs echo is off. in case of environment variable modified is deleted because the replace string is an empty string and the search string matches the entire line. The search string can't contain an equal sign because of = has a special meaning in substitution expression.
Is this code very different if I need to change two separate string like using another set "modified1=...?
Wow, this seems to be overkill for such a simple thing.
57
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!)

9 Comments

OK, so at least for a string, it's possible with Windows batch features (not compatible with DOS batch or older Windows versions). But I'd be surprised if this works on a file (especially a file with multiple lines).
@schnaader: It is possible, try a look at Batch FindAndReplace
@jeb: OK, so it's possible at least, thanks for the link. Anyway, both "very complicated" and "incompatible" from my answer apply here.
@schnaader: Generally, it's not as elegant as some other scripting tools might do. I suspect, that initially they were called batch files simply meaning batch executing (of commands). But I may be wrong there. Anyway, what with cscript and PowerShell being there, I sometimes think they would have scrapped batch files altogether if it were not for the probably enormous number of scripts still in use all over the Windows realm.
@Andriy M: It can be improved to be safe with ! and ^ in the content with toggling the delayed expansion on and off, like in Improved BatchSubstitute
|
12

To avoid blank line skipping (give readability in conf file) I combine aflat and jeb answer (here) to something like this:

@echo off
setlocal enabledelayedexpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"findstr /n ^^ %INTEXTFILE%"') do (
   SET string=%%A
   for /f "delims=: tokens=1,*" %%a in ("!string!") do set "string=%%b"
   if  "!string!" == "" (
       echo.>>%OUTTEXTFILE%
   ) else (
      SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
      echo !modified! >> %OUTTEXTFILE%
  )
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%

1 Comment

you may also want to set the correct code-page, to avoid problems with non-ansi characters in the text-file: e.g. chcp 65001 for UTF8: see Echo UTF-8 characters in windows batch
4

To avoid problems with the batch parser (e.g. exclamation point), look at Problem with search and replace batch file.

Following modification of aflat's script will include special characters like exclamation points.

@echo off
setlocal DisableDelayedExpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=bath
set REPLACETEXT=hello
set OUTPUTLINE=

for /f "tokens=1,* delims=¶" %%A in ( '"type %INTEXTFILE%"') do (
    SET string=%%A
    setlocal EnableDelayedExpansion
    SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!

    >> %OUTTEXTFILE% echo(!modified!
    endlocal
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%

Comments

0

I have made a function for that, you only call it in a batch program within needing to code more.

The working is basically the same as the others, as it's the best way to do it.
Here's the link where I have that function

Comments

-1

To avoid blank line skipping just replace this:

echo !modified! >> %OUTTEXTFILE%

with this:

echo.!modified! >> %OUTTEXTFILE%

1 Comment

This isn't an answer to the question
-8

If you have Ruby for Windows,

C:\>more file
bath Abath Bbath XYZbathABC

C:\>ruby -pne "$_.gsub!(/bath/,\"hello\")" file
hello Ahello Bhello XYZhelloABC

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.