Page 1 of 1

Delete specified multiple lines of a not in use batch file through another batch file?

Posted: 03 Apr 2021 15:15
by D4rks1d3r
this is is a little program i made to launch games with the Project64 Emulator:

Code: Select all

@echo off

echo Type 1 for Super Mario 64, type 2 for Ocarina of Time, type 3 for Majora's Mask

set /p input=

if %input%==1 goto Game1
if %input%==2 goto Game2
if %input%==3 goto Game3

:Game1
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Super Mario 64 (USA).z64"

exit

:Game2
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Ocarina of Time (USA).n64"

exit

:Game3
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Majora's Mask (USA).z64"

exit
now i want to remove from another batch file, only Game3 completely, that would be

Code: Select all

:Game3
,

Code: Select all

cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
,

Code: Select all

start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Majora's Mask (USA).z64"
and

Code: Select all

exit
, but when removing

Code: Select all

cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
and

Code: Select all

exit
i only want to remove that from Game3, is this even possible??

Re: Delete specified multiple lines of a not in use batch file through another batch file?

Posted: 21 Apr 2021 11:24
by Maylow
If the file you want to change is that explicit with data, the following code would accomplish the task:

Code: Select all

@echo off
setlocal enableDelayedExpansion
set findstr.Ia=0
set findstr.Ib=0
for /f "usebackq tokens=* delims=^" %%b in (
    `type subject.cmd`) do (
    echo("%%~b"|findstr /rc:"start notepad.exe" 2>nul >nul && (
        if "!findstr.Ia!" equ "1" (
            >>subject2.cmd echo(%%b
        )
        set findstr.Ia=1
    ) || (
        echo("%%~b"|findstr /rc:"echo file was opened" 2>nul >nul && (
            if "!findstr.Ib!" equ "1" (
                >>subject2.cmd echo(%%b
            )
            set findstr.Ib=1
        ) || (
            >>subject2.cmd echo(%%b
        )
    )
)
endlocal
exit /b
I would make a more generic function with parameters with the purpose to filter out and rewrite scripts based on passed arguments.
But the above code gets the job done with the code you've provided.

Edit: in this example I've chosen the filename 'subject.cmd' to contain the code you've provided.
So in the above example subject.cmd contains:

Code: Select all

@echo off

start notepad.exe "C:\Users\Giovanni\Desktop\New folder\file1.txt"
echo file was opened

:flag
start notepad.exe "C:\Users\Giovanni\Desktop\New folder\file1.txt"
echo file was opened

Re: Delete specified multiple lines of a not in use batch file through another batch file?

Posted: 22 Apr 2021 04:12
by Maylow
I'd suggest to keep your original post original and place updates in a reply/comment. Otherwise, people might get confused about the article. Just a friendly tip :wink:

Based on your current update of this article, I've created and tested some code.

Below I've adjusted your code a bit to make it work with the other code I made.
Notice the REM statements, I've used them as start and end markers to find the requested code:

Code: Select all

@echo off

echo Type 1 for Super Mario 64, type 2 for Ocarina of Time, type 3 for Majora's Mask

set /p input=

if %input%==1 goto Game1
if %input%==2 goto Game2
if %input%==3 goto Game3

REM Game1 start
:Game1
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Super Mario 64 (USA).z64"

exit
REM Game1 end

REM Game2 start
:Game2
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Ocarina of Time (USA).n64"

exit
REM Game2 end

REM Game3 start
:Game3
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Majora's Mask (USA).z64"

exit
REM Game3 end
Here is the code that removes the parts you requested.
I've put it into functions for reusability.
Function labelList lists labels in a batch script and puts them into a return variable.
Function filterScript filters out the requested code.

Code: Select all

@echo off
call:filterScript "subject.cmd" "Game3" "subject2.cmd"
exit /b

:filterScript Script Marker [Output]
setlocal enableDelayedExpansion
call:labelList "%~f1" filterScript.Labels
for /f "tokens=1,* delims=:" %%b in (
    'findstr /rbinc:".*" "%~f1"'
) do (
    for /f "tokens=1,* delims=:" %%d in (
        'echo("%%~c"^|findstr /ric:"REM %~2 start"'
    ) do (
        if "!MarkerStart!" equ "" set "MarkerStart=%%b"
    )
    for /f "tokens=1,* delims=:" %%d in (
        'echo("%%~c"^|findstr /ric:"REM %~2 end"'
    ) do (
        if "!MarkerEnd!" equ "" set "MarkerEnd=%%b"
    )
)
for /f "tokens=1,* delims=:" %%b in (
    'findstr /rbinc:".*" "%~f1"'
) do (
    set LineText=%%c
    for %%l in (!filterScript.Labels!) do (
        if "%%~c" equ "%%~l" set LineText=:%%c
    )
    if %%~b geq !MarkerStart! (
        if %%~b leq !MarkerEnd! (
            REM Skip line !LineText! @%%b
        ) else (
            if "%~3" neq "" (
                >>"%~f3" echo(!LineText!
            ) else (
                >>"%~f1" echo(!LineText!
            )
        )
    ) else (
        if "%~3" neq "" (
            >>"%~f3" echo(!LineText!
        ) else (
            >>"%~f1" echo(!LineText!
        )
    )
)
endlocal
exit /b

:labelList Script [Rtn]
setlocal EnableDelayedExpansion
set "labelList.File=%~1"
if not exist "!labelList.File!" set "labelList.File=%~f0"
set "labelList.Rgx= *"
set "labelList.Rgx= *<*:@*[-a-z0-9_.\\\[\]/]*[-a-z0-9_.\\\[\]/#$]"
set "labelList.Rgx=!labelList.Rgx![-a-z0-9_.]*"
for /f "tokens=* delims=:" %%b in (
    'findstr /rbic:"!labelList.Rgx!" "!labelList.File!"'
) do (
    if "%~2" neq "" (
        if "%~2" neq " " (
            for /f "tokens=1" %%u in ("%%~b") do (
                set "labelList.Rtn=!labelList.Rtn:<:=!%%u "
            )
        ) else echo(%%b
    ) else echo(%%b
)
if "!labelList.Rtn!" neq "" (
    set "labelList.Rtn=!labelList.Rtn:~0,-1!"
    for /f "usebackq tokens=1,* delims==" %%b in (
        `set labelList.Rtn`) do (endlocal
        set "%~2=%%~c"
    )
) else endlocal
exit /b
Results/output:

Code: Select all

@echo off

echo Type 1 for Super Mario 64, type 2 for Ocarina of Time, type 3 for Majora's Mask

set /p input=

if %input%==1 goto Game1
if %input%==2 goto Game2
if %input%==3 goto Game3

REM Game1 start
:Game1
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Super Mario 64 (USA).z64"

exit
REM Game1 end

REM Game2 start
:Game2
cd "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\---"
start Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\Legend of Zelda, The - Ocarina of Time (USA).n64"

exit
REM Game2 end

Edit: it seems I forgot about the part that says 'if %input%==3 goto Game3' :oops:
But perhaps you can resolve that easily.
You can use the same tactic with the code I've provided.
Just place some start and end markers in a REM statement surrounding the parts you want to filter out and call filterScript with marker specified.
If the scripts you want to filter are automatically generated with other code, you can also adjust that other code to add these REM and call filterScript statements.

Re: Delete specified multiple lines of a not in use batch file through another batch file?

Posted: 22 Apr 2021 09:03
by D4rks1d3r
Sorry, i'm new here. This is way to complex for me to understand but thank you so much for the effort you put in it!!!

Re: Delete specified multiple lines of a not in use batch file through another batch file?

Posted: 22 Apr 2021 14:16
by Squashman
You should consider a redesign of the functionality of your script.
It would be better if you kept your Games as a list or in a separate file. Then use a script to iterate that list or file to make a Menu system.

Here is an example of creating the list within a FOR command.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set /a "GameNo=0"
set "choices="

REM PLACE GAMES inside the parentheses of the FOR command quote surrounded.
FOR %%I IN (
	"Super Mario 64 (USA).z64"
	"Legend of Zelda, The - Ocarina of Time (USA).n64"
	"Legend of Zelda, The - Majora's Mask (USA).z64"
) do (
	set /a GameNo+=1
	call :ResolveChar !GameNo!
	set "GameName!retval!=%%~I"
	set "choices=!choices!!retval!"
	echo [!retval!] %%I
)

choice /c !choices! /cs /m "Select Your Game: " /n
call :ResolveChar %errorlevel%
set "Game=!GameName%retval%!"
echo Game: %Game%
start "%Game%" /D "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\" Project64.exe "C:\Users\Giovanni\Desktop\Emuladores\Nintendo 64\Roms\%Game%"

pause
goto :eof

:ResolveChar
SETLOCAL
  set "keys=_ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  set "_startchar=%1"
  CALL SET "char=%%keys:~%_startchar%,1%%"
ENDLOCAL & SET "retval=%char%"

goto :eof
Again instead of having the list within the FOR command you could have a FOR command that reads a text file with a list of programs. Then all you have to do is edit the text file.
That FOR command would look like this.

Code: Select all

FOR /F "usebackq delims=" %%I IN ("gamelist.txt") do (
	set /a GameNo+=1
	call :ResolveChar !GameNo!
	set "GameName!retval!=%%~I"
	set "choices=!choices!!retval!"
	echo [!retval!] %%I
)