Ok i'm trying to write a batch to "grab" a serial number for the user. The serial number comes from another system and we have to periodically manually input a serial number. I would like the user to run the batch file which would add 1 and replace the old number and then echo "Your serial number is ##" where ## is the new number. I'm pretty sure i can work out the Echo part and the writing to a temp file and overwriting the old file but its the middle part that im struggling with. The xml file is that is being edited is:
<?xml version="1.0"?>
<BatchSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SerialFormat>{0:yyMMdd}{1:00}</SerialFormat>
<LastSerialDate>2020-05-27T00:00:00-05:00</LastSerialDate>
<LastSerialNumber>10</LastSerialNumber>
</BatchSettings>
the number i need to change is the ## between "lastserialnumber" <LastSerialNumber>10</LastSerialNumber>
.
I've tried a few different approaches and this first one is close but definitely no cigar.
@echo off
set /a "replace=10"
set /a "replaced=replace+1"
set "source=Test.txt"
set "target=Test2.txt"
setlocal enableDelayedExpansion
(
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
set "line=%%b"
if defined line set "line=!line:%replace%=%replaced%!"
echo(!line!
)
) > %target%
endlocal
The problem with that one is the number won't always be "10" and I also don't want to replace all the other instances of "10" in the file.
I've also tried
@Echo Off
Set "SrcFile=Test.txt"
Set "OutFile=Test2.txt"
@echo off
setlocal enableextensions disabledelayedexpansion
(for /f "delims=" %%a in (%SrcFile%
) do for /f "tokens=2 delims=1234567890 " %%b in ("%%~a"
) do if not "%%b"==":" (
echo(%%~a
) else for /f "tokens=1 delims= <LastSerialNumber>:" %%c in ("%%~a"
) do (
set /a "n=%%c+1"
setlocal enabledelayedexpansion
echo(<LastSerialNumber>!n!:
endlocal
)) > %OutFile%
but that doesn't increment the number and cuts off the remaining text. and this one is just a hot mess that doesn't work at all.
@Echo Off
Set "SrcFile=Test.txt"
Set "OutFile=Test2.txt"
setlocal EnableDelayedExpansion
(for /F "delims=" %%a in ('findstr /I /L "<LastSerialNumber>" %SrcFile%') do (
set "line=%%a
set "line=!line:*<LastSerialNumber>=!"
for /F "delims=<" %%b in ("!line!") do echo %%b+1
)) > %oldnumber%
set "newnumber=%oldnumber%+1"
(
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" %SrcFile%') do (
set "line=%%b"
if defined line set "line=!line:%oldnumber%=%newnumber%!"
echo(!line!
)
) > %OutFile%
endlocal
At first let us take a quick look at your attempts:
10
and does not regard the <LastSerialNumber>
tags at all.delims=
option of for /F
although it actually defines a set of characters.>
) into a variable, which cannot work, you can only redirect to files. Furthermore, you attempt to do arithmetics (+1
) but this only works when using set /A
. And the last section has got the same problem as approach 1.Here is a way you could do it:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~1" & rem // (input file; `%~1` is the first argument)
set "_TAG=<LastSerialNumber>" & rem // (opening tag)
rem // Loop over all (non-empty) lines of the input file:
for /F "usebackq delims=" %%L in ("%_FILE%") do (
rem // Store current line string:
set "LINE=%%L"
rem // Toggle delayed expansion to avoid troubles with `!`:
setlocal EnableDelayedExpansion
rem // Split off opening tag from line string:
set "TEST=!LINE:*%_TAG%=!"
rem // Check whether opening tag has been found:
if not "!TEST!"=="!LINE!" (
rem // Opening tag found, hence split off closing tag:
for /F "tokens=1* eol=< delims=< " %%S in ("!TEST!") do (
rem // Get extracted number and increment it:
set /A "NUM=%%S+1"
rem // Return rebuild line with incremented number:
echo( !_TAG!!NUM!^<%%T
)
) else (
rem // Opening tag not found, hence return original line:
echo(!LINE!
)
endlocal
)
endlocal
exit /B
Given the batch file is called inc-serial.bat
, call it with the input XML file as a command line argument (say test.xml
in the current directory):
inc-serial.bat "test.xml"
To write the output to another file use redirection (>
):
inc-serial.bat "test.xml" > "test_NEW.xml"