Reputation: 313
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
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