@ECHO OFF
SETLOCAL
:: The directory to look for data files and to place processed files
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
:: the start of the line, and length-to-match
SET "replaceinlines=20"
SET /a lengthofmatch=2
:: Replacement text, length-to-replace, column-for secondary-replacement
SET "replaceby=10101"
SET /a replacelength=6
SET /a replacecolumn=332
:: Replace-only-if-match ?
SET "replaceifmatch=Y"
:: calculate length of second-segment-to-preserve and its start-position
SET /a seg2start=replacelength+lengthofmatch
SET /a seg2=replacecolumn-seg2start
SET /a seg3start=replacecolumn+replacelength
::
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
FOR /f "usebackqdelims=" %%x IN ("%sourcedir%\%%a") DO SET "line=%%x"&call:process
) >"%destdir%\%%a"
GOTO :EOF
:process
:: does the start-of-line match?
CALL SET "startofline=%%line:~0,%lengthofmatch%%%"
IF "%startofline%" neq "%replaceinlines%" GOTO report
:: matched start-of-line; pick up data-to-replace
CALL SET "data1=%%line:~%lengthofmatch%,%replacelength%%%"
CALL SET "data2=%%line:~%replacecolumn%,%replacelength%%%"
::
:: Not sure about this - replace-both-regardless or replace-if-data-matches
::
IF "replaceifmatch"=="Y" IF "%data1%" neq "%data2%" GOTO report
CALL SET "line=%startofline%%replaceby%%%line:~%seg2start%,%seg2%%%%replaceby%%%line:~%seg3start%%%"
:report
ECHO(%line%
GOTO :eof
You would need to change the setting of sourcedir and destdir to suit your circumstances. Produces a new file with the same filename as the source in the destination directory. U: is my test drive.
Patching your supplied data yielded the target 400693 at column 332, ot 340 as claimed.
The pattern to match at the start of the lines is placed in replaceinlines and its length in lengthofmatch
The length of the text-to-be-replaced is 6 (replacelength) but you have a replacement string of length 5.?? (replaceby)
I look at the line as havng 4 segments - the first is the 20 and the following 6 characters, the second the space between that and the second 'to be replaced' string; the last (which I named seg3 but should be seg4 is the part which follows the second 'to-be-replaced' string.
You don't say whether the replacement is to take place only if the two 'to-be-replaced' strings match or regardless, so I supplied a switch replaceifmatch - Y means "if the two match, replace both". Setting replaceifmatch to something else will replace regardless.
Beyond that, it's a simple matter of calculating the column-positions and lengths from the data provided and using call set to apply the calculated values to the strings of interest.