Patillac
Patillac

Reputation: 313

How to delete list of files in batch file

I'm attempting to delete all non-code files from directories and their subdirectories using a batch script. Using the command prompt I can verify the results of the script, but when the script is executed it does not perform the actions one would expect.

for /F %%F in ('dir /s /b /a-d ^| findstr /vile ".c .cpp .h .hpp"') do if "%%~fF" neq      "%~f0" del /S /Q "%%F"

When extracting and executing the following command, the paths produced are correct:

dir /s /b /a-d | findstr /vile ".c .cpp .h .hpp"

However, when executing it via the batch file the resulting paths sent to the 'del /S /Q "%%F"' command are the first subdirectory over and over.

The following is a comparison of the command prompt output and the batch file output (with the del command replaced by echo)

Console:

C:\testdata\delete_test>dir /s /b /a-d | findstr /vile ".c .cpp .h .hpp"
C:\testdata\delete_test\delete_non_code_files.bat
C:\testdata\delete_test\delete_test - Copy\7328_log.txt
C:\testdata\delete_test\delete_test - Copy\7588_log.dat
C:\testdata\delete_test\delete_test - Copy\7964_log.txt
C:\testdata\delete_test\delete_test - Copy\8860_log.txt
C:\testdata\delete_test\delete_test - Copy (2)\7328_log.txt
C:\testdata\delete_test\delete_test - Copy (2)\7588_log.dat
C:\testdata\delete_test\delete_test - Copy (2)\7964_log.txt
C:\testdata\delete_test\delete_test - Copy (2)\8860_log.txt
C:\testdata\delete_test\delete_test - Copy (3)\7328_log.txt
C:\testdata\delete_test\delete_test - Copy (3)\7588_log.dat
C:\testdata\delete_test\delete_test - Copy (3)\7964_log.txt
C:\testdata\delete_test\delete_test - Copy (3)\8860_log.txt

Batch file:

C:\testdata\delete_test>delete_non_code_files.bat
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"
/S /Q "C:\testdata\delete_test\delete_test"

Why doesn't my %%F variable point to a file as 'for /F' should cause it to do?

Upvotes: 3

Views: 3650

Answers (1)

dbenham
dbenham

Reputation: 130819

The FOR /F command parses each line into tokens, and the default token delimiters are <space> and <tab> and by default, only the 1st token is preserved. You need to force the entire line to be one token by setting DELIMS to nothing. Also, the EOL option is ; by default, meaning any line that begins with ; will be skipped. Technically, a folder or file name can begin with ;, so the EOL option should be set to something that cannot start a valid path. The : is a good candidate.

Totally unrelated, but you don't need the /S or /Q options in this situation.

for /F "eol=: delims=" %%F in ('dir /s /b /a-d ^| findstr /vile ".c .cpp .h .hpp"') do if "%%~fF" neq "%~f0" del "%%F"

Upvotes: 3

Related Questions