Replacing strings with batch file command - batch-file

I have many files that are name "12739-5468768.xml", what they have in common is the "12739", inside these files I want to replace every & with " AND " and every </ with nothing. I tried many commands and python command but it doesn't seem to operate on my computer.
#echo off
setlocal
setlocal enabledelayedexpansion
set "search=&"
set "replace= AND "
set "textfile=12739*"
set "newfile=Output.txt"
(
for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
set "line=!line:%search%=%replace%!"
echo(!line!
)
) > "%newfile%"
del %textfile%
rename %newfile% %textfile%
endlocal

Solution for a single file
This handles also !^, empty lines and lines beginning with ; in the file content.
#echo off
setlocal
call :replaceFile "12739-5468768.xml"
exit /b
:replaceFile
set "search=&"
set "replace= AND "
set "textfile=%~1"
set "newfile=%~1.replaced"
setlocal DisableDelayedExpansion
(
for /f "usebackq delims=" %%i in (`findstr /N "^" "%textfile%"`) do (
set "line=%%i"
setlocal EnableDelayedExpansion
set "line=!line:*:=!"
if defined line (
set "line=!line:%search%=%replace%!"
set "line=!line:</=!"
)
(echo(!line!)
endlocal
)
) > "%newfile%"
endlocal
exit /b

Download something called "FART"
then include it in the folder of the batch then do a bat with this code
"#echo off
FART -i -r "12739*" "&" " AND " "

You need to escape the & Ampersand using the ^ character.
#echo off
setlocal
setlocal enabledelayedexpansion
set "search=^&"
set "replace= AND "
set "textfile=12739*"
set "newfile=Output.txt"
(
for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
set "line=!line:%search%=%replace%!"
echo(!line!
)
) > "%newfile%"
del %textfile%
rename %newfile% %textfile%
endlocal

Related

Find and replace text with an incremental counter

I am trying to write a Windows batch script which can replace text with an incremented counter.
I have a playlist with tv channels and I would like to replace each channel number throughout the playlist.
My playlist has this structure:
#EXTM3U
#EXTINF:-1,ACS NETWORK TV
http://127.0.0.1:6878/ace/getstream?id=***&.mp4
#EXTINF:-1,Ani
http://127.0.0.1:6878/ace/getstream?id=***&.mp4
#EXTINF:-1,Boomerang HD (France)
http://127.0.0.1:6878/ace/getstream?id=***&.mp4
#EXTINF:-1,BoomerŠ°ng TV
http://127.0.0.1:6878/ace/getstream?id=***&.mp4
I want to replace #EXTINF:-1, with:
#EXTINF:-1, 1
#EXTINF:-1, 2
#EXTINF:-1, 3
#EXTINF:-1, 4
etc.
My script have following structure:
findstr /c:"EXTINF" "C:\Users\home\Links\Desktop\TV-Playlist.m3u" | find /c /v "GarbageStringDefNotInYourResults" > C:\Users\home\Links\Desktop\1111.count
set /p VAR=< C:\Users\home\Links\Desktop\1111.count
for /L %%n in (1,1,%VAR%) do (
setlocal enableextensions disabledelayedexpansion
set "search=#EXTINF:-1,"
set "replace=#EXTINF:-1,!%%n! "
set "textFile=C:\Users\home\Links\Desktop\TV-Playlist.m3u"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line:%search%=%replace%!
endlocal
)
)
Here is one solution based on your code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PlayListFile=C:\Users\home\Links\Desktop\TV-Playlist.m3u"
if not exist "%PlayListFile%" goto EndBatch
set "Counter=1"
for /F "delims= eol=" %%I in ('type "%PlayListFile%" ^& break ^> "%PlayListFile%" ') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
if "!Line:#EXTINF:-1,=!" == "!Line!" (
>>"%PlayListFile%" echo(!Line!
endlocal
) else (
>>"%PlayListFile%" call echo !Line:#EXTINF:-1,=#EXTINF:-1,%%Counter%% !
endlocal
set /A Counter+=1
)
)
:EndBatch
endlocal
But it removes empty lines from file because FOR always ignores empty lines.
This code keeps also empty lines:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "PlayListFile=C:\Users\home\Links\Desktop\TV-Playlist.m3u"
if not exist "%PlayListFile%" goto EndBatch
set "Counter=1"
set "TempFile=%TEMP%\%~n0.tmp"
(for /F "delims= eol=" %%I in ('%SystemRoot%\System32\findstr.exe /N /R "^" "%PlayListFile%"') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if not defined Line (
echo(
endlocal
) else if "!Line:#EXTINF:-1,=!" == "!Line!" (
echo(!Line!
endlocal
) else (
call echo !Line:#EXTINF:-1,=#EXTINF:-1,%%Counter%% !
endlocal
set /A Counter+=1
)
))>"%TempFile%"
if not %Counter% == 1 move /Y "%TempFile%" "%PlayListFile%"
if exist "%TempFile%" del "%TempFile%"
:EndBatch
endlocal
For details on this solution see How to read and print contents of text file line by line?
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
move /?
set /?
setlocal /?
So, if I understand your question, and if I can do one suggest:
Put 1 for to handle the counter and do rename the string, after all, replace the file:
#echo off && setlocal enableextensions enabledelayedexpansion
set _m3u_file_in="%userprofile%\Links\Desktop\TV-Playlist.m3u"
set _m3u_file_out="%userprofile%\Links\Desktop\TV-Playlist_New.m3u"
set _cnt=0&& type nul >!_m3u_file_out!
for /f "tokens=* delims= " %%i in ('type !_m3u_file_in! ^|findstr /lbc:"#EXTINF:-" ^|findstr /r "[0-9][\,]" ') do (
set "_old_=%%i"&& call set /a _cnt=!_cnt! + 1
set "_new_=#EXTINF:-1,!_cnt!!_new:~10!"
)
echo/ Total lines replace: !_cnt!
move /y !_m3u_file_out! !_m3u_file_in!

Batch, use wildcard in set

I want to put a batch file to modify a line in a file in a GPO.
The problem I have is the path is different for each user.
So, I tried to use a wildcard in my path but it doesnt work.
This bat is working:
#echo off &setlocal
setlocal enabledelayedexpansion
set "search=test"
set "replace=test2"
set "textfile=%appdata%\Thunderbird\Profiles\5xu9scdm.default\prefs.js"
set "newfile=%appdata%\Thunderbird\Profiles\5xu9scdm.default\prefs2.js"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
set "line=!line:%search%=%replace%!"
echo(!line!
))>"%newfile%"
del %textfile%
rename %newfile% prefs.js
endlocal
But if I use a wildcard in the set, it doesnt work anymore.
#echo off &setlocal
setlocal enabledelayedexpansion
set "search=test"
set "replace=test2"
set "textfile=%appdata%\Thunderbird\Profiles\*.default\prefs.js"
set "newfile=%appdata%\Thunderbird\Profiles\*.default\prefs2.js"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
set "line=!line:%search%=%replace%!"
echo(!line!
))>"%newfile%"
del %textfile%
rename %newfile% prefs.js
endlocal
How can I fix this ?
You approach does not work, because wild-cards can only occur in the last element of a path. In addition, for /F is not capable of handling wild-cards. So you need to wrap around a for /D loop to resolve the wild-cards, like this (supposing there is only a single matching directory *.default):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "search=test"
set "replace=test2"
set "rootdir=%appdata%\Thunderbird\Profiles\*.default"
set "textfile=prefs.js"
set "newfile=prefs2.js"
for /D %%j in ("%rootdir%") do (
> "%%~j\%newfile%" (
for /F "usebackq delims=" %%i in ("%%~j\%textfile%") do (
set "line=%%i"
setlocal EnableDelayedExpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
)
)
> nul move /Y "%%~j\%newfile%" "%%~j\%textfile%"
)
endlocal
exit /B
What I changed besides inserting the for /D loop:
delayed expansion is toggled within the loop, so exclamation marks in the text files are not lost;
all paths are properly quoted; to use a quoted file path in for /F, usebackq is required;
the replacement of the original file by the modified one is done by a single move command rather than del plus rename;

bat script for replacing strings creates empty file

I'm using this bat file to modify a value in a web.config from httpTransport to httpsTransport. It works well if I direct my output to another file. If I try to overwrite my file it creates an empty file.
#echo off &setlocal
set "search=httpsTransport"
set "replace=http123Transport"
set INTEXTFILE=D:\teste_bat\Web.config
set OUTTEXTFILE=D:\teste_bat\WebTemp.config
(for /f "delims=" %%i in ('findstr "^" "%INTEXTFILE%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>>"%OUTTEXTFILE%"
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
Any help would e apreciated
The following code fails in case both INTEXTFILE and OUTTEXTFILE point to the same file, because the output redirection > prepares the output file at the beginning, so it creates an empty file, which is then read by findstr:
set "INTEXTFILE=D:\teste_bat\Web.config"
set "OUTTEXTFILE=D:\teste_bat\Web.config"
> "%OUTTEXTFILE%" (
for /f "delims=" %%i in ('findstr "^" "%INTEXTFILE%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
)
)
Replacing > by >> does also not work, because this appends the new data to the original file.
To overcome this, you have got two options:
To write to a different file and to replace the original file by the new one at the end:
set "INTEXTFILE=D:\teste_bat\Web.config"
set "OUTTEXTFILE=D:\teste_bat\WebTemp.config"
> "%OUTTEXTFILE%" (
for /f "delims=" %%i in ('findstr "^" "%INTEXTFILE%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
)
)
move /Y "%OUTTEXTFILE%" "%INTEXTFILE%"
This is the recommended variant due to better performance.
To ensure that the file is read before the output redirection is applied:
set "INTEXTFILE=D:\teste_bat\Web.config"
set "OUTTEXTFILE=D:\teste_bat\Web.config"
for /f "delims=" %%i in ('findstr "^" "%INTEXTFILE%" ^& ^> "%OUTTEXTFILE%" rem/') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
>> "%OUTTEXTFILE%" echo(!line!
endlocal
)
This is worse in performance since there are multiple file access operations (appending to the file per each loop iteration due to >>), but it prevents the need of a temporary file. The portion > "%OUTTEXTFILE%" rem/ depletes the file after being read by findstr, then it is appended to later in the loop body.

Batch file to Replace underscore(_)from header of text file

I got a Pipe(|) separated file new.txt. I want to create a batch file which replaces underscore characters from new.txt keeping the data intact. I have created a batch which replaces underscore even from data. Please help.
new.txt contains header
Transaction_Type|Spend_Source_System|Event_ID|Expense_ID
Batch code I have written is
#echo off &setlocal
set "search=_"
set "replace= "
set "textfile=D:\test.txt"
set "newfile=D:\test2.txt"
(for /f %%i in ('findstr "^" "%textfile%"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
type "%newfile%"
(for /f "DELIMS=" %%i in ('findstr "^" "%textfile%"') do (
should fix your problem.
Ah - it would appear they you may wish to replace the underscores only in the header line.
set "search=_"
set "replace= "
set "textfile=D:\test.txt"
set "newfile=D:\test2.txt"
SET header=Y
(for /f "delims=" %%i in ('findstr "^" "%textfile%"') do (
IF DEFINED header (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
ENDLOCAL
SET "header="
) ELSE (ECHO(%%i)
))>"%newfile%"

Insert new lines(which has a command) after a particular line in batch file using batch file

I want to insert a line which has a command(mkdir/copy) in a batch file after a particular line using a batch file.(mkdir/copy command should be considered as a word rather than command)
Input:
set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB
copy /Y %QBprovisionpath%\x86\Debug %ConnectorExecutionPath%\x86\Debug
Output:
set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB
copy /Y %ConnectorExecutionPath%\%outqbsyncpath%
mkdir /Y %ConnectorExecutionPath%\%outqbsyncpath%
copy /Y %QBprovisionpath%\x86\Debug %ConnectorExecutionPath%\x86\Debug
A New line copy /Y %ConnectorExecutionPath%\%outqbsyncpath% - which has a copy command and mkdir /Y %ConnectorExecutionPath%\%outqbsyncpath% which has mkdir command, get inserted after a particular line set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB
SETLOCAL ENABLEDELAYEDEXPANSION
set inputFile=%userprofile%\desktop\testSO.bat
set outputFile=%userprofile%\desktop\testSOout.bat
set _strInsert=set IndbBankpath=C:\InstallerOutput\QuickBooks-Sync\indb
set _strFind=set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB
set i=0
FOR /F "usebackq tokens=1 delims=[]" %%A IN (FIND /N "%_strFind%" "%inputFile%") DO (set _strNum=%%A)
FOR /F "usebackq delims=" %%A IN ("%inputFile%") DO (
set /a i = !i! + 1
ECHO %%A>>"%outputFile%"
IF [!i!] == [%_strNum%] (
ECHO %_strInsert%>>"%outputFile%"
ECHO I WANT TO ADD THIS LINE ALSO>>"%outputFile%"
ECHO OOOO THIS LiNE TOO>>"%outputFile%"
ECHO ZOMGBBQSAUCE ADD THIS LINE ALSO>>"%outputFile%"
)
)
The above code doesn't work if I change set _strInsert=copy /Y %ConnectorExecutionPath%\%outqbsyncpath% or set _strInsert=mkdir %ConnectorExecutionPath%\%outqbsyncpath%
Please suggest a solution for this.
#echo off
set "particularLine=set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB"
setlocal DisableDelayedExpansion
if exist output.bat del output.bat
for /F "delims=" %%a in (input.bat) do (
echo %%a
set "line=%%a"
setlocal EnableDelayedExpansion
if "!line!" == "!particularLine!" (
echo copy /Y %%ConnectorExecutionPath%%\%%outqbsyncpath%%
echo mkdir /Y %%ConnectorExecutionPath%%\%%outqbsyncpath%%
)
endlocal
) >> output.bat
Previous Batch file has several drawbacks: it remove empty lines and may fail if the line contain quotes.
EDIT: New version added
The Batch file below run faster if the input file is large; it also have several details fixed, like not removing empty lines.
#echo off
setlocal EnableDelayedExpansion
set "inputFile=%userprofile%\desktop\testSO.bat"
set "outputFile=%userprofile%\desktop\testSOout.bat"
set "particularLine=set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB"
for /F "usebackq delims=:" %%a in (`findstr /N /C:"!particularLine!" "%inputFile%"`) do set theLine=%%a
if exist "%outputFile%" del "%outputFile%"
if not defined theLine echo The particular line doesn't exist in Input file & exit /B
setlocal DisableDelayedExpansion
set i=0
for /F "usebackq delims=" %%a in (`findstr /N "^" "%inputFile%"`) do (
set "line=%%a"
set /A i+=1
setlocal EnableDelayedExpansion
echo(!line:*:=!
if !i! eql %theLine% goto exitLoop
endlocal
) >> "%outputFile%"
:exitLoop
rem Insert here all the lines to insert, each one preceeded by ECHO
(
echo copy /Y "%%ConnectorExecutionPath%%\%%outqbsyncpath%%"
echo mkdir /Y "%%ConnectorExecutionPath%%\%%outqbsyncpath%%"
) >> "%outputFile%"
setlocal DisableDelayedExpansion
for /F "skip=%theLine% usebackq delims=" %%a in (`findstr /N "^" "%inputFile%"`) do (
set "line=%%a"
setlocal EnableDelayedExpansion
echo(!line:*:=!
endlocal
) >> "%outputFile%"
Please note that you must double the percent signs in the commands to insert; otherwise what is inserted is the current value of the variables instead of the %name% of the variables.
I believe the only problem you're running into is the fact that you're not encapsulating your paths for the COPY and MKDIR commands:
set _strInsert=mkdir %ConnectorExecutionPath%\%outqbsyncpath%
Try:
set _strInsert=mkdir "%ConnectorExecutionPath%\%outqbsyncpath%"
I would also do a check for the folder before creating it as well.
EDIT:
Now if you're adding in a bunch of different lines, just add them to the code. In your previous post you asked to add a single line to the code. If you're doing multiple lines, just echo them directly into the output file.
SETLOCAL ENABLEDELAYEDEXPANSION
set inputFile=%userprofile%\desktop\testSO.bat
set outputFile=%userprofile%\desktop\testSOout.bat
set _strFind=set MTBBankpath=C:\InstallerOutput\QuickBooks-Sync\MTB
set i=0
FOR /F "usebackq tokens=1 delims=[]" %%A IN (FIND /N "%_strFind%" "%inputFile%") DO (set _strNum=%%A)
FOR /F "usebackq delims=" %%A IN ("%inputFile%") DO (
set /a i = !i! + 1
ECHO %%A>>"%outputFile%"
IF [!i!] == [%_strNum%] (
ECHO set IndbBankpath=C:\InstallerOutput\QuickBooks-Sync\indb
ECHO copy /Y "%ConnectorExecutionPath%\%outqbsyncpath%"
ECHO mkdir /Y "%ConnectorExecutionPath%\%outqbsyncpath%"
ECHO copy /Y "%QBprovisionpath%\x86\Debug %ConnectorExecutionPath%\x86\Debug"
)>>"%outputFile%"
)

Resources