Pong
Pong

Reputation:

Batch Script IF

I'm trial and erroring a trivial batch script:

I need to execute the .bat and have it iterate through all the files in the current directory and delete all files (and subfolders) except for itself and two other files.

This works:

@echo off
for /f %%f in ('dir /b c:\d\test') do (del %%f)

This doesn't:

@echo off
for /f %%f in ('dir /b c:\d\test') do (if (true) (del %%f))

Why? (in place of "if (true)" I'd like to say "if not filename=='foo' or filename=='bar'" etc)

Many thank you's

EDIT: @rangerchris, perfect, thanks. now how to include folders and subfolderrs in the iteration?

Upvotes: 0

Views: 1624

Answers (3)

Jay
Jay

Reputation: 1655

Pong, in this code, fill the "Keep" variable with the needed filenames.

I took for granted that those files cound be anywhere so in the test I really check the name+extension only, not the path, so they could be inany sub-path.

EDIT: Ok, there goes the revised more deeply tested version for Pong. Sorry for posting too hastily, wanted to help but guess I didn't test my script enough.

Although this time, allows me to show an example or recursive programming (function :CleanDirs calling itself) in XP batch programming :)

Cleanup.cmd:

@echo off
set Keep="%~nx0" "file1.ext" "file2.ext"
set StartDir=%~dp0
call :CleanDirs "%StartDir:~0,-1%"
exit /b 0
:CleanDirs
    call :CleanFiles "%~1"
    for /f "delims=" %%d in ('dir /ad /b "%~1"2^>nul') do call :CleanDirs "%~1\%%~d"
    if exist "%~1" rmdir /Q "%~1">nul 2>nul
    exit /b 0
:CleanFiles
    for /f "delims=" %%f in ('dir /a-d /b "%~1"2^>nul') do (
        set _keep=
        for %%k in (%Keep%) do if /i "%%~nxf"=="%%~k" set _keep=yes
        if not defined _keep del /f "%~1\%%~f" 2>nul
    )
    exit /b 0

Still, hope this helps even more.

Notes

set Keep= : Adjust with any filename you need to keep. The script will keep the subfolders holding those files.

set StartDir=%~dp0 : Will ajust itself to whereever the script is located. If you want to move the script elsewhere, you could call it with a directory name as argument and change assignation here as ="%~1"

Coding tips

%*~*1 : (Tild) remove enclosing quotes. Will not remove ALL quotes, only one leading/Trailing.

%~nx0 : (tild n x)gets the filename+ext of the batchfile. Warning, this will change if this is put into a function. Adjust as needed.

%~dp0 : (tild d p) Gets the drive/full path (including trailing baskslash (\) of the batchfile. Warning, this will change if this is put into a function. Adjust as needed.

%StartDir:~0,-1% : (Tild Start,Stop) Gets a substring of the variable, here from position 0 to last character minus one position (used to strip trailing \).

Upvotes: 1

Callie J
Callie J

Reputation: 31296

From the command line, it works okay here with:

for %i in (*) do if not "%i" == "startgd.bat" echo %i

Obviously, change %i to %%i in a .bat file though. What error (if any) are you getting? Maybe you just need to use the quotes correctly (double quotes rather than single?)

EDIT: For ignoring two files, this works:

for %i in (*) do if not "%i" == "startgd.bat" if not "%i" == "msdelog.log" echo %i

EDIT 2 [based on @Pong's edit to make this complete]: To recurse down folders, just pass the /s switch to dir. So you'll have something like:

for /f %i in ('dir /s /b c:\') do if not "%i" == "C:\startgd.bat" if not "%i" == "c:\path\to\other\file" echo %i

Upvotes: 0

ars
ars

Reputation: 123498

This should work:

for /f %%f in ('dir /b c:\d\test') do (if '%%f' == 'foo' del %%f)

Basically, you need to quote the variable in your conditional test.

Upvotes: 0

Related Questions