It seems to me that this is an "XY" problem in SO parlance, that is the problem presented is a faulty solution to an unstated problem.
The fundamental problem appears to be: Starting with a template file test.exe.conf
which contains a line <add key="FileName" value="20220623.txt"/>
, produce a new file having substituted a new value for 20220623
.
OP's code is designed to remove the <add key..
line, and there's nothing in that code to make a substitution.
Consequently, I'll present a solution aimed at curing the problem, not the code.
Since I'm making some assumptions about the problem, it may not be quite what is desired.
The first issue is what string to substitute for 22020623
- I'd conclude it's likely to change over time, so I've added a few line to enable that data to be supplied or entered instead of changing the batch file. This means that you could execute thisbatchname 20221008 to run the batch and produce a file with 20221008
substituted for 22020623
, or execute thisbatchname and the batch will prompt for the string to substitute for 22020623
. Be warned though that whatever string is entered in either case will be literally substituted.
The second issue is that I'm assuming that test.exe.conf
is a template file, so it can be manipulated - hence, take the original test.exe.conf
and modify it so that each <add key...
line is replaced by a unique string. I chose substitute line here
- but it could be almost any string - @#123
for instance.
@ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory,
rem filename, and output filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q73308290.txt"
SET "outfile=%destdir%\outfile.txt"
:: Get `newvalue`
SET "newvalue=%1"
IF NOT DEFINED newvalue SET /p "newvalue=New value ? "
IF NOT DEFINED newvalue GOTO :eof
(
FOR /f "usebackqdelims=" %%b IN ("%filename1%") DO (
IF /i "%%b"=="substitute line here" (
ECHO ^<add key="FileName" value="%newvalue%.txt"/^>
) ELSE ECHO %%b
)
)>"%outfile%"
GOTO :EOF
Always verify against a test directory before applying to real data.
Note that if the filename does not contain separators like spaces, then both usebackq
and the quotes around %filename1%
can be omitted.
The filenames shown suit my system and allow me to isolate the unique data for a question.
The file is assigned line-by-line to %%b
. If %%b
is not the trigger line substitute line here
then it's simply reproduced by the echo %%b
, but if it is a trigger line, then the required substitute line is generated instead.
All output from the echo
s is gathered into a new file outfile.txt
by means of surrounding the code causing the echo
es with a pair of parentheses and >filename
.
--- revision after comments
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory,
rem filename, and output filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q73308290.txt"
SET "outfile=%destdir%\outfile.txt"
:: Get `newvalue`
SET "newvalue=%1"
IF NOT DEFINED newvalue SET /p "newvalue=New value ? "
IF NOT DEFINED newvalue GOTO :eof
FOR /f "tokens=5delims==/ " %%e IN ('FINDSTR /i /R /c:".*add key=\"FileName\" value=\"[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].txt\"/." "%filename1%"') DO SET "oldfn=%%~e"&GOTO process
:process
(
FOR /f "usebackqdelims=" %%b IN ("%filename1%") DO (
ECHO "%%b"|FINDSTR /i /R /c:".*add key=\"FileName\" value=\"[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].txt\"/." >nul
IF ERRORLEVEL 1 (
ECHO %%b
) ELSE (
SET "line=%%b"
echo !line:%oldfn%=%newvalue%.txt!
)
)
)>"%outfile%"
:done
FC /w "%outfile%" "%filename1%"
GOTO :eof
Always verify against a test directory before applying to real data.
Note that if the filename does not contain separators like spaces, then both usebackq
and the quotes around %filename1%
can be omitted.
This time, %%e
acquires the ????????.txt
string from the line in question and assigns it to oldfn
.
The file is then processed, simply regurgitating lines that do not contain the required string, otherwise substituting the new value for the old filename, using DELAYEDEXPANSION
... although a solution using SED
would probably be cleaner if 3rd party utilities are allowed.