Question

i have the following code in batch (cmd):

for /f "delims=" %%f in ('dir /b /s Example') do (
command
if %errorlevel%==1 (
command
SKIP
)
command
)

EDIT: To make things more clear: for /f... searches for a directory called 'Example' and loops to search for more directories than one. the first command is a delete command, it deletes all files in the directory. the command that happens when an error occurs, is a echo command which writes some info about the error to a text file. now the hole skip thing; sometimes, the files can't be deleted because of access denied or this file is in use by.... Normally, what would happen if there weren't a skip thing, it would just stop the command and hang. So, what i want to do, is prevent this from happening. Alternatively, i want to use something like skip, so it can skip the file and continue anyways. So i think this command needs to be piped in the delete command.

I hope it's clear now.

Thanks in advance.

Was it helpful?

Solution

Like this?

for /f "delims=" %%f in ('dir /b /s Example') do (
  command
  if not errorlevel 1 (
    command-for-success
  ) else (
    command-for-error
  )
)

OTHER TIPS

Create the two command files and run delex.cmd. The files and directories that are not deleted will be logged to delex.txt. The ones that hang, will have a minimized cmd window open that gets killed after a delay by using ping (thanks to Doc Brown's suggestion).

delex2.cmd
----------
@echo off
del /q %1 
if exist %1 echo %1 not deleted!>>delex.txt 
exit 

delex.cmd
---------
@echo off
if exist delex.txt del delex.txt 
for /f "delims=" %%f in ('dir /s /b example') do start "delextaskkill" /min delex2.cmd "%%f"
ping 127.0.0.1 -n 3 -w 1000> nul
taskkill /fi "Windowtitle eq delextaskkill"> nul

Tested with:

\example
|   file1
|   file2
|   file3
|   file4
|   file5
|
\---example
        file1
        file2
        file3
        file4
        file5

When one uses del, and "access denied" or "this file is in use by..." occurs, %errorlevel% is 0, so testing %errolevel% is useless. Perhaps the following simple solution works in your case:

for /f "delims=" %%f in ('dir /b /s Example') do (
    del %%f
    if exist %%f (
         echo "file not deleted"
    ) else (
         echo "file deleted"
    )
 ) 

I believe that this is what you want

for /f "delims=" %%f in ('dir /b /s Example') do (
  command
  if not errorlevel 1 (
    command
  ) else (
    command
    goto :eof
  )
)

Perhaps this is more advanced than can be accomplished using just built-in cmd processing. Why not consider using the Windows Scripting Host (vbscript/jscript) or even PowerShell? Both will likely provide you the level of control you are requesting.

Try this batch file:

@echo off
REM For each directory named 'Example' ...
for /f "delims=" %%f in ('dir /b /s Example') do (
    REM .. enter the directory and delete all the files found there.
    pushd .
    cd %%f
    del /q *
    for /f "delims=" %%z in ('dir /b') do (
        REM Any files that still exist must have been inaccessable.  Log an error.
        echo Unable to delete file %%z > C:\logfile.txt
    )
    popd
)

Tested with the following directory structure:

folder\
|------Example\
|      |-------file1 (write-protected)
|      |-------file2
|      |-------file3
|------deeper\
       |-------Example\
               |-------file4
               |-------file5 (write-protected)
               |-------file6

After running the batch file, only file1 and file5 were left. An "Access is denied" message was printed for each write-protected file encountered; if that gets annoying you re-direct the output of the batch file like script.bat > NUL to hide it.

So after all the existing answers didn't satisfy you and you absolutely need a skip within your batch file, i will make another try:

@echo off
setlocal

for /f "delims=" %%f in ('dir /b /s batch') do call :DoSomething %%f
goto end

:DoSomething
echo Here i am: %1
if %errorlevel%==1 goto :eof

echo No error occured
goto :eof

:end
endlocal

The trick is, that the for loop calls a sub function within the same file and gives the needed parameter to it. This new call runs in a new context and can only access the variables which are defined after the do call :DoSomething in the given order their.

So you have to access the variables here with %1, %2, etc. If you want to leave this context you have to make a goto :eof to jump to the end of the file (this marker is predefined in batch mode and should not occur within your file), what leaves the context and returns to the for loop.

After running through the whole loop we just jump to the :end marker, make a little clean up and are finished.

The following looks for the file extentions you want recursively under the "dirname" directory tree and executes commandstuff.bat against that file name:

for /r %i in (c:\dirname\*.ext) do commandstuff "%i"

Commandstuff.bat looks like this:

@ECHO OFF
del %1
IF (%ERRORLEVEL% == 0) goto END
:ERROR
Echo Error deleting %1

:END
Echo end

This would run commandstuff.bat for you to delete the files you want. When there is an error it will simply echo the file details and continue processing the next file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top