I am using following code for deletion of older files
rem declaration des variables
set path=E:\somefiles
set delai_retention=15
rem Purge recursive des fichiers
%WINDIR%\system32\forfiles /p %path% /s /m * /d -%delai_retention% /c "cmd /c del /q #path"
opsexit %errorlevel%
rem Purge recursive des dossiers vides
%WINDIR%\system32\forfiles /p %path% /d -%delai_retention% -c "cmd /c if #ISDIR==TRUE rmdir /S /Q #FILE"
opsexit %errorlevel%
But while running the code every time my script ends with the following error
Could Not Find E:\somefiles\Thumbs.db
How to fix this error?
First, a hint, forfiles works without you need to go to the winsys32 folder; in fact, every .exe in winsys32 is available without that code. Code without that reduces the file lenght, that is good.
Either, some files needs supervision to being deleted. Use del /q /f /s, is more efficient.
Don't use "path" as a name, is a system variable, this will have conflict. And i think that cmd /c is useless.
I think so that is best use #path instead of #file in the other command.
These will be like that:
rem declaration des variables
set epath=E:\somefiles
set delai_retention=15
rem Purge recursive des fichiers
forfiles /p %epath% /s /m * /d -%delai_retention% /c "del /q /f /s #path"
opsexit %errorlevel%
rem Purge recursive des dossiers vides
forfiles /p %epath% /d -%delai_retention% -c "if #ISDIR==TRUE rmdir /S /Q #PATH"
opsexit %errorlevel%
You can also add a >nul if your problem is with the responses. Like that:
rem declaration des variables
set epath=E:\somefiles
set delai_retention=15
rem Purge recursive des fichiers
forfiles /p %epath% /s /m * /d -%delai_retention% /c "del /q /f /s #path 0^>nul 1^>nul 2^>nul"
opsexit %errorlevel%
rem Purge recursive des dossiers vides
forfiles /p %epath% /d -%delai_retention% -c "if #ISDIR==TRUE rmdir /S /Q #PATH 0^>nul 1^>nul 2^>nul"
opsexit %errorlevel%
Now even if have some problem in deleting the file, won't be show.
I hope I helped you.
Related
I am trying to run a script to clear out the recycle bin on a QNAP NAS periodically.
The problem is the path for the recycle bin on the NAS includes an [at] sign:
"\nas01\SQLBackup\#Recycle" (Had to use double slash here to get it to display correctly)
Can someone please point me in the right direction as to what I'm doing wrong?
Thanks in advance for your help.
Batch File Code
#ECHO ON
NET USE X: "\\nas01\SQLBackup\#Recycle"
forfiles /p "X:\" /s /m * /c "cmd /c del #path"
NET USE X: /delete
PAUSE
Output
C:\Windows\system32>NET USE X: "\\nas01\SQLBackup\#Recycle"
The command completed successfully.
C:\Windows\system32>forfiles /p "X:\" /s /m * /c "cmd /c del #path"
ERROR: Invalid argument/option - '#path'.
Type "FORFILES /?" for usage.
C:\Windows\system32>NET USE X: /delete
X: was deleted successfully.
C:\Windows\system32>PAUSE
Press any key to continue . . .
The reason you get the error is due to the double quotes around the path, where backslash is present. The backslash escapes the last double quote. You should either use:
forfiles /p "X:" /s /m * /c "cmd /c del #path"
or
forfiles /p X:\ /s /m * /c "cmd /c del #path"
anyway, I would not use forfiles at all here. You can quite simply use del /s:
net use X: "\\nas01\SQLBackup\#Recycle"
pushd "x:\">nul 2>&1 && del /Q /S *.* || echo X:\ Not available.
popd
net use X: /delete
pause
Quite simply, we attempt pushd to x:\ if not available, it will fail with a message, if available it will del /s everything on X:\ where /s is basically recursive search throughout the root of X:\ in this instance.
The #-symbol in your path does not cause the error. It is the backslash in:
forfiles /p "X:\" /s /m * /c "cmd /c del #path"
that unintentionally escapes the closing quote (this is specific to forfiles!). To avoid that, simply append a . to the path, like:
forfiles /p "X:\." /s /m * /c "cmd /c del #path"
The . means current directory, so in a path it does not change anything, hence X:\ equals X:\., and D:\some\.\path equals D:\some\path. Of course, you could just remove the quotes around X:\ in your particular situation, but appending . is a general solution that even works with a relative path like X: (meaning the current directory of drive X:), and removal of quotes introduces problems with paths containing SPACEs.
By the way, are you aware that forfiles returns both files and directories, and that del is there to delete just files, and there is rd to delete directories?
So to ensure to handle only files, use this:
forfiles /S /P "X:\." /M * /C "cmd /C if #isdir==FALSE del #path"
And to ensure to handle only directories, use this:
forfiles /S /P "X:\." /M * /C "cmd /C if #isdir==TRUE rd /S /Q #path"
Of course you can handle both, if you want:
forfiles /S /P "X:\." /M * /C "cmd /C if #isdir==TRUE (rd /S /Q #path) else (del #path)"
When you use PushD, it will create a temporary drive map, (allocated in available reverse alphabetical order, Z:..A:), and will then use that new drive. For that reason you should be able to do this without using net.exe.
Example:
#PushD "\\nas01\SQLBackup\#Recycle" 2> NUL && (RD /S /Q . 2> NUL & PopD)
This example uses RD to Remove the Directory instead of your used Del command. When the target directory is the current working directory, it cannot be removed, (returning an error message), however its contents will be. The code above redirects the error message to the NUL device, so that it is not output.
i would like to know how you can delete multiple files in different folders with batch commands.
I have the following code, this code works fine for 1 map but i need to do it for multiple maps :
forfiles /p "D:\CHILI_Publisher\Data\Environments\Adecco\Cache_Data\Assets" /s /d -10 /c "cmd /c echo #file"
PAUSE
This is the code for the various maps and various file types with wildcards (this one gives an error : The directory name is invalid:
forfiles /p "D:\CHILI_Publisher\Data\Environments\*.*\Cache_Data\*.*" /s /d -10 /c "cmd /c echo #file"
PAUSE
Tl;DR : I have an error and would like to know how to use a wildcard correctly in batch files.
You can wrap FORFILES in a FOR loop:
for /d %D in (c:\temp\a*;c:\temp\b*;c:\temp\c*) do forfiles /p %D /s /c "cmd /c echo #file" /d -10
If you need to find all folders named CACHE_DATA under a super folder you can navigate to the super folder (cd D:\CHILI_Publisher\Data\Environments) and run this:
for /f %F in ('dir /B /S /AD cache_data') do for /d %D in (%F) do forfiles /p %D /s /c "cmd /c echo #file" /d -10
If you put the script in a BATCH file remember to escape % with %%.
I am just getting into Bat files.
I am trying to delete old folders on a network shared drive but skip 2 of the containing folders by name.
Basically I need to all files that I make daily and always keep 2 old files.
Code that deletes all files that are older than 3 days:
PushD "\\****-****\build" &&(
ForFiles /D -3 /C "CMD /C if #ISDIR==TRUE echo RD #FILE &RD /S #FILE
) & PopD
And I was thinking something like this: if NOT #FNAME == %name%. I don't totally understand the process, am I able to have two conditions in the forFiles? do I have to have /c before?
PushD "\\****-****\build" &&(
ForFiles /D -3 /C "CMD /C if NOT #FNAME == %name% if #ISDIR==TRUE echo RD #FILE &RD /S #FILE
) & PopD
I can't seem to get it, would you mind helping me out?
Thanks!
Yes, nesting if commands in their then branches is the way how-to have logical AND. Note proper quoting in next code snippet:
#ECHO ON >NUL
#SETLOCAL enableextensions
set "name=SO"
set "nam2=SU"
pushd "D:\VB_scripts"
#rem all directories
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE echo #FILE"
#rem all directories except "SO"
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""%name%""" echo #FILE"
#rem all directories except "SO" and "SU"
ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""%name%""" if not #FNAME=="""%nam2%""" echo #FILE"
popd
#ENDLOCAL
Output:
==>D:\bat\SO\31346676.bat
==>set "name=SO"
==>set "nam2=SU"
==>pushd "D:\VB_scripts"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE echo #FILE"
"Class Pack"
"Oldies"
"SO"
"SU"
"WMI"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""SO""" echo #FILE"
"Class Pack"
"Oldies"
"SU"
"WMI"
==>ForFiles /D -2 /C "CMD /C if #ISDIR==TRUE if not #FNAME=="""SO""" if not #FNAME=="
""SU""" echo #FILE"
"Class Pack"
"Oldies"
"WMI"
==>popd
It is a little bit messy but I was able to do it on a local directory:
#echo off
mkdir Temp\Temp
REM Copy all old file to Temp dir
forfiles -p "%cd%" -m *.* /D -2 /C "cmd /c xcopy #path %cd%\Temp"
REM copy a random file from Temp dir to Temp/Temp dir and then delete it
FOR %%A in (%cd%\Temp\*) do (
COPY "%%A" %cd%\Temp\Temp\
DEL "%%A"
GOTO :Second
)
:Second
Rem copy second random file from Temp dir
FOR %%A in (%cd%\Temp\*) do (
COPY "%%A" %cd%\Temp\Temp\
GOTO :Del
)
:Del
Rem delete all old files from local dir
forfiles -p "%cd%" -m *.* /D -2 /C "cmd /c del #path"
Rem Copy back two random old files to local dir
xcopy %cd%\Temp\Temp\* %cd%
Rem remove Temp dir
rmdir /s /q Temp
I want to create a batch file which should delete all subfolders of a folder which are older than 10 days, using Windows 7
Any help would be appreciated.
Adapted from this answer to a very similar question:
FORFILES /S /D -10 /C "cmd /c IF #isdir == TRUE rd /S /Q #path"
You should run this command from within your d:\study folder. It will delete all subfolders which are older than 10 days.
The /S /Q after the rd makes it delete folders even if they are not empty, without prompting.
I suggest you put the above command into a .bat file, and save it as d:\study\cleanup.bat.
FORFILES /S /D -10 /C "cmd /c IF #isdir == TRUE rd /S /Q #path"
I could not get Blorgbeard's suggestion to work, but I was able to get it to work with RMDIR instead of RD:
FORFILES /p N:\test /S /D -10 /C "cmd /c IF #isdir == TRUE RMDIR /S /Q #path"
Since RMDIR won't delete folders that aren't empty so I also ended up using this code to delete the files that were over 10 days and then the folders that were over 10 days old.
FOR /d %%K in ("n:\test*") DO (
FOR /d %%J in ("%%K*") DO (
FORFILES /P %%J /S /M . /D -10 /C "cmd /c del #file"
)
)
FORFILES /p N:\test /S /D -10 /C "cmd /c IF #isdir == TRUE RMDIR /S /Q #path"
I used this code to purge out the sub folders in the folders within test (example n:\test\abc\123 would get purged when empty, but n:\test\abc would not get purged
If you want using it with parameter (ie. delete all subdirs under the given directory), then put this two lines into a *.bat or *.cmd file:
#echo off
for /f "delims=" %%d in ('dir %1 /s /b /ad ^| sort /r') do rd "%%d" 2>nul && echo rmdir %%d
and add script-path to your PATH environment variable. In this case you can call your batch file from any location (I suppose UNC path should work, too).
Eg.:
YourBatchFileName c:\temp
(you may use quotation marks if needed)
will remove all empty subdirs under c:\temp folder
YourBatchFileName
will remove all empty subdirs under the current directory.
I am running a batch file and I have one forfiles command in it
FORFILES -p%spinputarchrootpath% -m*.csv -d-365 -c"CMD /C DEL #FILE"
%spinputarchrootpath% variable maps to a folder location (Y:\Temp Documents\testfolder).
Now the above command is throwing an error because of the space in the folder name (Temp Documents).
How to handle this space? I have tried putting quotes around %spinputarchrootpath% variable but it is not working.
I'd the same problem and found the solution.
I think your folder-variable of the folder you wish to empty has a backslash at the end.
This will NOT work:
echo J|forfiles /P "C:\temp files\" /S /M * /D -7 /C "cmd /c del /F /S /Q #path"
... but this works (without backslash)
echo J|forfiles /P "C:\temp files" /S /M * /D -7 /C "cmd /c del /F /S /Q #path"
Regards
Tino
Enclose the path in quotes:
FORFILES -p "%spinputarchrootpath%" -m *.csv -d -365 -c "CMD /C DEL #FILE"
Note, there's a space between -p and "%spinputarchrootpath%". Without a space in this case it won't work.
As a work around first change directories to the folder you want, and then execute forfiles without the /p parameter.
CD %spinputarchrootpath%
FORFILES -m*.csv -d-365 -c"CMD /C DEL #FILE"
Check post:
How to Tell FORFILES to Execute Command on Path?
The problem lies in the part:
-c"CMD /C DEL #FILE"
Use:
-c"CMD /C DEL ^0x22#FILE^0x22"
to put extra double quotes around the file