0

I want to do something along the lines of:

for %%i not in (*.xml *.doc) do ....

Obviously, that doesn't work. Is there a way I can do something similar in a batch file?

skittleys
  • 353
  • 1
  • 3
  • 11

3 Answers3

3
for /f "eol=: delims=" %%i in ('dir /b /a-d *^|findstr /live ".bat .txt"') do ...

Addendum

This solution will slow down in a non-linear fashion if the directory listing becomes huge. This is unlikely to be a problem with a single directory, but can easily become a problem if the DIR /S option is used. The solution can be restored to having a linear response time with respect to listing size by using temp files.

set temp1="%temp%\dirExclude1_%random%.txt"
set temp2="%temp%\dirExclude2_%random%.txt"
>%temp1% dir /s /b /a-d *
>%temp2% findstr /live ".bat .txt" %temp1%
for /f "usebackq eol=: delims=" %%i in (%temp2%) do ...
del %temp1%
del %temp2%

This is a general limitation with Windows pipes. They become very inefficient with large amounts of data. It is always much faster to use temp files instead of a pipe when dealing with large amounts of data.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Yes, that definitely worked, and it's much simpler than the proposed alternatives! But how does it work? I've figured out most of it but the *^| is new to me. – skittleys Apr 12 '12 at 05:00
  • If you have a lot of files and speed matters, Aacini's solution is probably faster (I did not measure, but shelling out is expensive) – Anders Apr 12 '12 at 05:14
  • @Anders - I've done the test, and the Aacini solution was actually 2.5 times SLOWER. Also the Aacini solution fails with `=` or `!` in the file name. My solution will slow down disproportionally if the dir size is HUGE, but that can be fixed by redirecting the DIR to a tempFile1, using FINDSTR to create tempFile2, and then using tempFile2 in the FOR IN clause instead of the piped command. But this optimization should only be needed in extraordinary circumstances. – dbenham Apr 12 '12 at 10:14
1
@echo off
setlocal EnableDelayedExpansion
rem Build a list of files to exclude
set exclude=
for %%i in (*.xml *.doc) do set "exclude=!exclude!%%i*"
rem Process all but excluded files
for %%i in (*.*) do (
   if "!exclude!" equ "!exclude:%%i*=!" echo Process this one: %%i
)
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • 1) I believe you intended `"!exclude:.%%i.=!"` in your IF statement. 2) Will not work properly if file name contains `=`. 3) Problem if both `"a.txt"` and `"a.txt.doc"` exist - easily solved by using `*` as a delimiter instead of `.` since `*` cannot exist in file name or path. – dbenham Apr 12 '12 at 02:48
  • 1
    My mistake, should use `?` instead of `*` or `.`. Initialize `set exclude=?` and in IF use `!exclude:?%%i?=!`. Another alternative is to use `:` as delimiter, but that could cause problems if FOR /R option is used with full path in `%%i`. – dbenham Apr 12 '12 at 03:24
  • This solution will also fail if a file name contains `!` because delayed expansion is enabled. Fixing this limitation will slow it down considerably. There is no good, practical way to allow for `=` in the file name with this solution. – dbenham Apr 12 '12 at 10:24
0
@echo off
cls
set folder=C:\Users\MARKETING 1\Desktop\CONDIVISA
cd /d "%folder%"
for /f "delims=" %%i in ('dir /b') do (
    if not "%%i"=="FILE SALVATI QUI VERRANNO CANCELLATI AUTOMATICAMENTE OGNI SABATO.txt" (
        if exist "%%i" (
            if /i "%%~ai"=="d" (
                rmdir "%%i" /s/q
            ) else (
                del "%%i" /q
            )
        )
    )
)
attrib +r "FILE SALVATI QUI VERRANNO CANCELLATI AUTOMATICAMENTE OGNI SABATO.txt"
del /q *.*
rd /s /q .
attrib -r "FILE SALVATI QUI VERRANNO CANCELLATI AUTOMATICAMENTE OGNI SABATO.txt"

That is a batch file which deletes all files and subfolders excluding the file named:

FILE SALVATI QUI VERRANNO CANCELLATI AUTOMATICAMENTE OGNI SABATO.txt
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • The __FOR__ loop ignores directories and files with hidden attribute set and does not delete files with read-only attribute set. The command `del /q *.*` ignores also files with hidden attribute set and does not delete files with read-only attribute set. The command `rd /s /q .` deletes all directories and files including the file which should not be deleted at all. I recommend to look on [Batch delete all files and directories except specified file and directory](https://stackoverflow.com/a/57110498/3074564) how to code the deletion of all files and directories with exceptions correct. – Mofi Mar 27 '23 at 10:54
  • 1
    This code is an unnecessary long version of [How to delete files/subfolders in a specific directory at the command prompt in Windows?](https://stackoverflow.com/a/50656521/3074564) because of `cd /d "%folder%"` and `rd /s /q .` with the disadvantage on deleting everything in current folder whatever the current folder is if the `cd` command failed to change the current directory because of the directory assigned to the environment variable does not exist at all. It is a very dangerous batch file for that reason and is definitely not a solution for the task to delete nearly all files. – Mofi Mar 27 '23 at 11:00