Search code examples
windowsbatch-filecmdforfiles

I want a batch file to delete all files in an absolute path location (F:\work) except two files named "txt1.txt" and "txt2.txt"


I am using a cmd batch code to delete all files inside F:\Work folder except a file txt1.txt, the folder contains two files txt1.txt and txt2.txt.

This is the batch code I am using:

forfiles /p "f:\Work" /s /m *.*  /C "cmd /c if not @file==txt1.txt del @path" 

It is deleting both txt1.txt and txt2.txt. What is wrong?


Solution

  • There is no need to use forfiles for your task, a standard for loop is perfectly suitable:

    for /R "F:\Work" %%I in (*) do if /I not "%%~nxI"=="txt1.txt" del "%%~I"
    

    However, if you insist on using forfiles, then:

    1. Do not specify mask /M *.* but use /M * instead (which is anyway the default), because the former skips files with no extension.
    2. Regard that forfiles iterates over both files and directories, so use /C "cmd /C if @isdir==FALSE …" to process files only.
    3. Escape quotes inside of forfiles' /C string, like \" or 0x22. (I prefer the latter since the " in \" is still recognised by the command processor, which might require additional ^-escaping in some situations, potentially leading to quite complicated and illegible escape sequences.)
    4. Note that all file-name-related @-variables return quoted values, so if [not] @file==txt1.txt will never [not] match, but if [not] @file==\"txt1.txt\" will [not], and if /I [not] @file==\"txt1.txt\" will even ignore the case (as said escape " like \").

    Hence the correct command line is:

    forfiles /S /P "F:\Work" /M * /C "cmd /C if @isdir==FALSE if /I not @file==\"txt1.txt\" del @path"
    

    Or, with alternative quote escaping and skipped mask:

    forfiles /S /P "F:\Work" /C "cmd /C if @isdir==FALSE if /I not @file==0x22txt1.txt0x22 del @path"