Windows batch file replace text issue - batch-file

I have this code to replace some text in JS file:
#echo off &setlocal
set "search=showLog: true"
set "replace=showLog: false"
set "textfile=globalsDebugTest.js"
set "newfile=new.js"
(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%"
The problem with this script is that it adds a line number in every new line.
I just want to replace this string: "showLog: true" with this: "showLog: false".
Any idea how to do it?

for /f "tokens=1*delims=:" %%h in ('findstr /n "^" "%textfile%"') do (
(note the addition of a tokens= phrase, delims is assigned : and the loop metavariable is changed to h.)
adding the tokens= means the metavariable h receives the number before the delimiter (colon) and i the remainder of the line after the colon. This keeps the changes on one line.
Another option would be to simply drop the /n from the findstr which will have the consequence of removing all empty lines from the output.

Related

How do i read a text file INCLUDING empty lines in batch?

I want to make it so that the empty lines are also outputted. For eg, this is my example.txt file.
Hello
This is a text file. Hello World!
And my code to run it is,
for /f "delims=" %%a in (%cd%\example.txt) DO (
echo. %%a
)
But it doesnt show the empty lines and instead shows it like
Hello
This is a text file. Hello World!
How do I make it so it shows the empty line too? Thanks!
FOR /F ignores empty lines, but you can use findstr to prefix each line with a line number, then there aren't empty lines anymore.
setlocal EnableDelayedExpansion
FOR /F "delims=" %%L in ('findstr /N "^" "%~dp0\example.txt"') DO (
set "line=%%L"
set "line=!line:*:=!" & rem Remove all characters to the first colon
echo(!line!
)
The problem with delayed expansion is that it destroys all ! and ^ characters from your file.
Therefore, you could toggle the mode.
setlocal DisableDelayedExpansion
FOR /F "delims=" %%L in ('findstr /N "^" "%~dp0\example.txt"') DO (
set "line=%%L"
setlocal EnableDelayedExpansion
set "line=!line:*:=!" & rem Remove all characters to the first colon
echo(!line!
endlocal
)

Batch Script - Findstr "/n" flag?

I found a example of what I wanted to do online, which was search a text file for a string and replace only that string and write out to a file. Which sort-of works...
The script does replace the correct text. But, its printing line numbers, which I don't want. However, if I remove the \n flag from findstr, it only prints lines containing data, and lines that aren't comments *(i.e. beginning with ";;").
How do I use findstr to print all the lines without the line numbers?
#echo off &setlocal
set "search=string to replace"
set "replace=replace string with me"
set "textfile=input.ini"
set "newfile=output.ini"
(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%"
The /n switch is required to keep the empty lines, so if want the empty lines in input be copied to the output you should not remove /n switch from findstr otherwise you do not need findstr and can directly read file with FOR. instead you can remove the line numbers by this modified code of yours:
#echo off
setlocal
set "search=string to replace"
set "replace=replace string with me"
set "textfile=input.ini"
set "newfile=output.ini"
(for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "%textfile%"') do (
if "%%j" NEQ "" (
set "line=%%j"
setlocal enabledelayedexpansion
echo(!line:%search%=%replace%!
endlocal
) else (
echo(
)
))>"%newfile%"
type "%newfile%"
Also there is no need for set "line=!line:%search%=%replace%!" you can directly pass !line:%search%=%replace%! to echo
Or you can get ride of findstr altogether and simply write the FOR loop as below but you will loos empty lines
(for /f "usebackq delims="eol^= %%i in ("%textfile%") do (
set "line=%%i"
setlocal enabledelayedexpansion
echo(!line:%search%=%replace%!
endlocal
))>"%newfile%"
Please note that in "usebackq delims="eol^= there must be no spaces between the quotation mark(") and eol. It is not a typo.
This is to disable the default eol character(;) so the lines that beginning semicolon(;) will not be ignored by FOR /F command

How to find and replace text in a file using batch script

I have an existing file named client.props, I need to create a batch script to read the document and find root= and replace it with root=path_of_file. I have used the below mentioned script:
#echo off
setlocal enableextensions disabledelayedexpansion
set "search=root="
set "replace=root=%~dp0"
set "textFile=client.props"
set "textFile1=client1.props"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile1%" ') do
(
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
>>"%textFile1%" echo(!line!
endlocal
)
I am not that great in batch scripts, kindly help me out with this. If file is available in F:\temp\file\client.props with one of the line starts with root= then the batch should modify it as root=F:\temp\file.
Before:
root=
After:
root=F:\temp\file
The = sign cannot be used within the sub-string replacement syntax !line:%search%=%replace%!, because the = separates the search string and the replacement string.
You could change your for /F loop so that it splits every line at the = character and checks the left part against root and the right one against being empty:
#echo off
setlocal enableextensions disabledelayedexpansion
set "search=root="
set "replace=root=%~dp0"
set "textFile=client.props"
set "textFile1=client1.props"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile1%" ') do (
>>"%textFile1%" (
for /f "tokens=1,* delims==" %%a in ("%%i") do (
if /i "%%a="=="%search%" (
if "%%b"=="" (
echo(%replace%
) else (
echo(%%i
)
) else (
echo(%%i
)
)
)
)
As you can see there is not even delayed expansion necessary. This approach however fails if there is a line like =root==, because leading delimiters are ignored and subsequent delimiters are treated as one. To do a case-sensitive search string comparison, remove the /i option from the if command line.
Note that the replaced line is terminated with a \, like root=F:\temp\file\, for example.

Batch - edit single line in file

I was searching for a batch script which edits a specific and known line in another batch-file.
I found this solution (Stackoverflow: Batch - edit specified line in text file) and it was almost workiing properly. The only problem I had with the script from Endoro is that it deletes the colons at the start of a line which I don't want to edit. Is there a way to avoid this from happening?
Help would be much appreciated! Thanks in advance!
#ECHO OFF &SETLOCAL
:Input
set /p version=Please Enter Version:
:Replacement
SET "file=test.bat"
SET /a Line#ToSearch=4
SET "Replacement=set jversion = %Version%_x86"
(FOR /f "tokens=1*delims=: " %%a IN ('findstr /n "^" "%file%"') DO (
SET "Line=%%b"
IF %%a equ %Line#ToSearch% SET "Line=%Replacement%"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO(!Line!
ENDLOCAL
))>"%file%.new"
TYPE "%file%.new"
MOVE "%file%.new" "%file%"
for /F treats subsequent delimiters as one. findstr /N precedes every line with a line number and a colon. So for instance if the third line is :abcd ef, for /F receives 3::abcd ef. After parsing the two tokens, you will get 3 and abcd ef. That is why leading colons disappear.
To overcome this, use sub-string replacement syntax; supposing variable Line contains the entire line including the line number prefix (string 3::abcd ef from above), use SET "Line=!Line:*:=!" to remove everything up to and including the first colon (so the resulting string is :abcd ef).
To get the line number, use another for /F loop with : as delimiter, fetching the first token only.
Here is the fixed script:
#ECHO OFF &SETLOCAL
:Input
set /p version=Please Enter Version:
:Replacement
SET "file=test.bat"
SET /a Line#ToSearch=4
SET "Replacement=set jversion = %Version%_x86"
(FOR /f "delims=" %%a IN ('findstr /n "^" "%file%"') DO (
SET "Line=%%a"
rem // Use a `for /F` loop to extract the line number:
for /F "delims=:" %%N in ("%%a") do set "LNum=%%N"
SETLOCAL ENABLEDELAYEDEXPANSION
rem // Use sub-string replacement to split off
rem // the preceding line number and one colon:
SET "Line=!Line:*:=!"
IF !LNum! equ %Line#ToSearch% SET "Line=%Replacement%"
ECHO(!Line!
ENDLOCAL
))>"%file%.new"
TYPE "%file%.new"
MOVE "%file%.new" "%file%"

I am writing a .bat program to find and replace text in a file without changing its position

I am writing a .bat program that will find and replace text in a file. The problem that I am having is that it is removing blank lines and left justifying the other lines. I need the blank lines to remain and the new text to remain in the same location. Here is what I have wrote, and also the result. Can anybody please help.
program:
#ECHO OFF
cls
cd\
c:
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (samplefile.tx) do (
Set str=%%a
set str=!str:day=night!
set str=!str:winter=summer!
echo !str!>>samplefile2.txt)
ENDLOCAL
cls
exit
samle File:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
day
winter
below is the result:
this line is the first line in my file that I am using as an example.This is made up text
the cat in the hat
night
summer
I need the lines, spaces and new text to remain in the same position while making the text replacement. Please help
Your use of "tokens=* delims= " will trim leading spaces. Instead, use "delims=" to preserve leading spaces.
FOR /F always skips empty lines. The trick is to insert something before each line. Typically FIND or FINDSTR is used to insert the line number at the front of each line.
You can use !var:*:=! to delete the the line number prefix from FINDSTR.
Use echo(!str! to prevent ECHO is off message when line is empty
It is more efficient (faster) to redirect only once.
#echo off
setlocal enableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
)
)
This still has a potential problem. It will corrupt lines that contain ! when %%A is expanded because of the delayed expansion. The trick is to toggle delayed expansion on and off within the loop.
#echo off
setlocal disableDelayedExpansion
>samplefile2.txt (
for /f "delims=" %%A in ('findstr /n "^" samplefile.txt') do (
set "str=%%A"
setlocal enableDelayedExpansion
set "str=!str:*:=!"
set "str=!str:day=night!"
set "str=!str:winter=summer!"
echo(!str!
endlocal
)
)
Or you could forget custom batch entirely and get a much simpler and faster solution using my JREPL.BAT utility that performs regular expression search and replace on text. There are options to specify multiple literal search/replace pairs.
jrepl "day winter" "night summer" /t " " /l /i /f sampleFile.txt /o sampleFile2.txt
I used the /I option to make the search case insensitive. But you can drop that option to make it case sensitive if you prefer. That cannot be done easily using pure batch.
#ECHO Off
SETLOCAL
(
FOR /f "tokens=1*delims=]" %%a IN ('find /n /v "" q27459813.txt') DO (
SET "line=%%b"
IF DEFINED line (CALL :subs) ELSE (ECHO()
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof
Thi should work for you. I used a file named q27459813.txt containing your data for my testing.
Produces newfile.txt
Will not work correctly if the datafile lines start ].
Revised to allow leading ]
#ECHO Off
SETLOCAL
(
FOR /f "delims=" %%a IN ('type q27459813.txt^|find /n /v "" ') DO (
SET "line=%%a"
CALL :subs
)
)>newfile.txt
GOTO :EOF
:subs
SET "line=%line:*]=%"
IF NOT DEFINED line ECHO(&GOTO :EOF
SET "line=%line:day=night%"
SET "line=%line:winter=summer%"
ECHO(%line%
GOTO :eof

Categories

Resources