0

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:

Batch Script - Find and replace text in multiple files in a directory without asking user to install any program or add other files to my batch script

@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>
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • 1
    Change the line `set "LINE=%%L" & set "FLAG="` to `set "LINE=%%L"` and put `set "FLAG="` as a separate line before `for /F "delims=" %%L ...`; this seems to be a flaw of the original script already... – aschipfl Aug 06 '19 at 10:13
  • 1
    I corrected the original code in the linked [answer](https://stackoverflow.com/a/46469094) meanwhile... – aschipfl Aug 06 '19 at 11:03
  • 1
    Since the issue is now handled [elsewhere](https://stackoverflow.com/a/46469094) let me suggest to delete this question... – aschipfl Aug 06 '19 at 11:37
  • Thank you aschipfl and this works perfectly. But I have another problem with it, would you please help before I delete the question? (I can't figure out if./how to PM). Though the file is now fixed it won't import correctly because it has the same name as the program being imported into. I don't mean file name. I mean a line like this: **LL&C Way 1: Portavadie to Tighnabruaich** however after that are many subsequent other **** tags. How in the same file could the FIRST instance of **** be changed to **fixed **? – Marty JG Aug 06 '19 at 15:11
  • What about using the search string `LL&C Way 1: Portavadie to Tighnabruaich` and the replace string `LL&C Way 1: Portavadie to Tighnabruaich fixed`? – aschipfl Aug 06 '19 at 15:35
  • How many times will we rewrite `sed`? – lit Aug 06 '19 at 17:27
  • aschipfl thanks for the reply - because the text between the varies, and it's not the ONLY use of name in the file. It's the FIRST use of . However I have fixed that, by creating a FIRST flag and a recreation of your replacement test, hardcoding a look for . And that brings me to the next problem. Sometimes Flag, Blue isn't in the file so there is nothing to replace, but the program defaults to the Blue Flags. So I'm trying to make it an IF ELSE situation. – Marty JG Aug 07 '19 at 16:25
  • lit - as far as I can tell SED is a compiled program and not available on every PC. This BAT file will be for sharing among the hiking & geocaching communities and it won't get half as much use if it has "download & install programs" requirements. – Marty JG Aug 07 '19 at 16:31

0 Answers0