I am trying to change all *.gpx files in a directory, editing out all instances of "Flag, Blue" with "Waypoint" (without quotation marks). I'm not great at Windows script and so want a little help debugging.
I have based this code on code by in question:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // based on code by aschipfl
rem // https://stackoverflow.com/questions/46467475/batch-script-find-and-replace-text-in-multiple-files-in-a-directory-without-as
rem // Define constants here:
set "_MASK=*.gpx" & rem // (working on all GPX files)
set "_SEARCH=Flag, Blue" & rem // (find those HORRIBLE blue flags)
set "_REPLAC=Waypoint" & rem // (repace with WAYPOINTS)
set "FOROPT=" & rem // NON-recursive
set "IFSW=" & rem // CaSe sEnSiTiVe YeS
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path to temporary file)
pushd "." || exit /B 1
rem // Loop through all matching files in the directory tree:
for %FOROPT% %%F in ("%_MASK%") do (
rem // Write to temporary file:
> "%_TMPF%" (
rem /* Read current file line by line; use `findstr` to precede every line by
rem its line number and a colon `:`; this way empty lines appear non-empty
rem to `for /F`, which avoids them to be ignored; otherwise empty lines
rem became lost: */
for /F "delims=" %%L in ('findstr /N "^" "%%~fF"') do (
rem // Store current line text:
set "LINE=%%L" & set "FLAG="
setlocal EnableDelayedExpansion
rem // Remove line number prefix:
set "LINE=!LINE:*:=!"
rem // Skip replacement for empty line text:
if defined LINE (
rem /* Use `for /F` loop to avoid trouble in case search or replace
rem strings contain quotation marks `"`: */
for /F "tokens=1* delims== eol==" %%I in ("!_SEARCH!=!_REPLAC!") do (
rem // Query to handle case-sensitivity:
if %IFSW% "!LINE!"=="!LINE:%%I=%%I!" (
rem // Detect whether replacement changes line:
if not "!LINE!"=="!LINE:%%I=%%J!" (
rem // Actually do the sub-string replacement:
set "LINE=!LINE:%%I=%%J!"
set "FLAG=#"
)
)
)
)
rem // Output the resulting line text:
echo(!LINE!
if defined FLAG (endlocal & set "FLAG=#") else (endlocal)
)
)
rem // Check whether file content would change upon replacement:
if defined FLAG (
rem // Move the temporary file onto the original one:
> nul move /Y "%_TMPF%" "%%~fF"
) else (
rem // Simply delete temporary file:
del "%_TMPF%"
)
)
popd
endlocal
exit /B
I run the script but no changes to the GPX files.
A real-world example segment from the GPX file would be:
<ele>1.19734255318821</ele>
<time>2019-07-28T00:42:12Z</time>
<name>CW1002</name>
<sym>Flag, Blue</sym>
<extensions>
<trp:ViaPoint>
Obviously I want this to remain the same except:
<sym>Waypoint</sym>