I have a batch file that works on my local machine (Windows 7), but doesn't fully work on the server it is intended to live on(Windows 2008 R2 Service Pack 1).
It needs to delete files older than a specified number of days in all listed folders, then delete empty folders and sub-folders.
Script:
set DaysOld=3
set "folders[0]=C:\Test\BatchDel\1"
set "folders[1]=C:\Test\BatchDel\2"
set "folders[2]=C:\Test\BatchDel\3"
set "folders[3]=C:\Test\BatchDel\DNE"
for /F "tokens=1* delims==" %%s in ('set folders[') do (
forfiles /p "%%t" /s /m * /D -%DaysOld% /C "cmd /c del #path"
)
for /f "delims=" %%d in ('dir /ad/b/s ^| sort /R') do rd "%%d"
pause
When run on my local machine (spacing added):
C:\Test\BatchDel>set DaysOld=3
C:\Test\BatchDel>set "folders[0]=C:\Test\BatchDel\1"
C:\Test\BatchDel>set "folders[1]=C:\Test\BatchDel\2"
C:\Test\BatchDel>set "folders[2]=C:\Test\BatchDel\3"
C:\Test\BatchDel>set "folders[3]=C:\Test\BatchDel\DNE"
C:\Test\BatchDel>for /F "tokens=1* delims==" %s in ('set folders[') do (forfiles /p "%t" /s /m * /D -3 /C "cmd /c del #path" )
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\1" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\2" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\3" /s /m * /D -3 /C "cmd /c del#path" )
ERROR: No files found with the specified search criteria.
C:\Test\BatchDel>(forfiles /p "C:\Test\BatchDel\DNE" /s /m * /D -3 /C "cmd /c del #path" )
ERROR: The specified directory does not exist.
C:\Test\BatchDel>for /F "delims=" %d in ('dir /ad/b/s | sort /R') do rd "%d"
C:\Test\BatchDel>rd "C:\Test\BatchDel\3"
C:\Test\BatchDel>rd "C:\Test\BatchDel\2"
C:\Test\BatchDel>rd "C:\Test\BatchDel\1"
The directory is not empty.
C:\Test\BatchDel>pause
Press any key to continue . . .
When I run it on the server it asks for permission to delete each folder. (spacing added).
F:\data\Scripts>set DaysOld=5
F:\data\Scripts>set "folders[0]=F:\data\Environments\TestA\Cache_Data"
F:\data\Scripts>set "folders[1]=F:\data\Environments\TestB\Cache_Data"
F:\data\Scripts>for /F "tokens=1* delims==" %s in ('set folders[') do (forfiles /p "%t" /s /m * /D -5 /C "cmd /c del #path" )
F:\data\Scripts>(forfiles /p "F:\data\Environments\TestA\Cache_Data" /s /m * /D -5 /C "cmd /c del #path" )
F:\data\Environments\TestA\Cache_Data\0432f59d-9fd1-46ed-8579-9ebe358113fb\*, Are you sure (Y/N)?
I need it to delete the empty folders on the server without pressing Y for each one.
EDIT:
I updated the script. Thanks aschipfl! it is now closer to working. It is now asking Y/N to delete each folder.
EDIT 2: updated the outputs.
I found this solution:
for /F "tokens=1* delims==" %%s in ('set folders[') do (
forfiles /p "%%t" /s /m *.* /D -%DaysOld% /C "cmd /c del #path"
for /f "delims=" %%d in ('dir "%%t" /s /b /ad ^| sort /r') do rd "%%d"
)
Related
This is a sample code that allows me to delete all folders with the name ".RemoveAsap" attached to them
#echo on
set dir="\\TestPC2\c$\Users"
FOR /D /R %dir% %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
pause
exit
Simply running the code as is runs perfectly but when I try to make the code more interactive, I get the error
#echo on
cd C:\Users\User1\Desktop\Test\
TYPE con >> LowDASD.txt
For /F %%A in (LowDASD.txt) do echo "\\%%A\c$\users\" >> LowDASD2.txt
set "LwDs"="LowDASD2.txt"
FOR /D /R "%LwDs%" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
pause
LowDASD2.txt would be the address/ directory location where the directories will be deleted, IE \\TestPC2\c$\Users
The code does not delete anything or give an error that "the path is too long" at least it was doing that with the previous variations that I was trying. If someone can help me with this, i would greatly appreciate it.
Try using FORFILES, instead of the command FOR, this way you can make it work like this:
:: forfiles /p "folder_location" 'args' '/c "cmd /c del /f /q #path"'
:: So...
cd C:\Users\User1\Desktop\Test\
TYPE con >> LowDASD.txt
For /F %%A in (LowDASD.txt) do echo "\\%%A\c$\users\" >> LowDASD2.txt
set "LwDs=LowDASD2.txt"
forfiles /p %LwDs% /s /c "cmd /c del /f /q #path"
:: You can use '/d -90' to delete files older than 90 days in the folder
FOR /D /R "%LwDs%" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
Simply will not work, as %LwDs% is a filename.
FOR /F "usebackq delims=" %%j in ("%LwDs%") do FOR /D /R "%%j" %%X IN (*.RemoveAsap) DO RMDIR /S /Q "%%X"
You would think might work - %%j being assigned to each entry in the %LwDs% file in turn; usebackq used because the filename is "quoted" (see for /? from the prompt for documentation)
But it doesn't - the for /d /r syntax doesn't accept metavariables...
So - try
FOR /F "usebackq delims=" %%j in ("%LwDs%") do set "target=%%j"&call :expunge
Where expunge is an internal subroutine. The colon is required
:expunge
echo target="%target%"
FOR /d /r "%target%" %%X IN (*.RemoveAsap) DO echo RMDIR /S /Q "%%X"
echo ====================
goto :eof
An internal subroutine should be placed after an unconditional goto, which should in your case follow the pause
pause
goto :eof
Where :eof (compulsory colon again) is defined as the physical end-of-file and should not be used as a user-label. Reaching physical end-of-file returns from a call.
Always verify against a test directory before applying to real data.
Note that the rmdir is merely being echoed for testing purposes - remove the echo keyword after testing to activate.
=== Extension
The full code should thus be
#echo on
set dir="\\TestPC2\c$\Users"
FOR /F "usebackq delims=" %%j in ("%LwDs%") do set "target=%%j"&call :expunge
pause
exit
:expunge
echo target="%target%"
FOR /d /r "%target%" %%X IN (*.RemoveAsap) DO echo RMDIR /S /Q "%%X"
echo ====================
goto :eof
This question already has answers here:
FORFILES date -after- (date calc in cmd file)
(2 answers)
Closed 1 year ago.
This finds no files (two in the directory are only one day old):
for /d %%d in (%mydir%\*) do (
cd %%d
forfiles /P %%d /M *.ppt* /D +7 /C "cmd /c echo Converting #file"
)
When I change the /D parameter to /D -6 it's ok,
also /D 25.10.2021 is ok.
But /D +7 never finds any file.
Is it a bug or feature?
Here's an example which is an adaption of what looks like the same method shown in aschipfl's answer within the link in their comment.
#Set "MyDir=%UserProfile%\Videos"
#For /F "Delims=" %%G In ('Dir "%MyDir%" /B /A:D 2^>NUL') Do #For /F "Delims=" %%H In ('^"Dir /B /A:-D 1^>NUL 2^>^&1 ^&^& %SystemRoot%\System32\forfiles.exe /P "%MyDir%\%%G" /D -0 /C "%SystemRoot%\System32\cmd.exe /D /C 0x22If #IsDir==FALSE %SystemRoot%\System32\forfiles.exe /M #File /D -8 1>NUL 2>&1 || Echo #Path0x22" 2^>NUL^"') Do #Echo Converting %%H
#Pause
I have left out any explanation, as the answer linked above, explains the methodology, this essentially wraps that methodology within a For /F loop.
I have created a batch script to delete 7 days older files as follows:
ForFiles /p "C:\Users\John.Kapen\Desktop" /s /d -7 /c "cmd /c del #file"
But this is deleting executable files and folders as well.
I tried below command to exclude executable file deletion. But not working:
for /f %%F in ('C:\Users\John.Kapen\Desktop /b /d -7 /a-d ^| findstr /vile ".exe"') do del "%%F"
Could someone help me here?
The forfiles /? "manpage" contains following information:
...
#ext - returns only the extension of the
file.
...
Examples:
...
FORFILES /M *.txt /C "cmd /c if #isdir==FALSE notepad.exe #file"
You can try something like (not tested):
ForFiles /p "C:\Users\John.Kapen\Desktop" /s /d -7 /c "cmd /c if NOT #ext=="""exe""" del #file"
F.e. there is some folder on user's desktop. I want to remove any files within this folder except shortcuts. There are two types of shortcuts - to some local\network resources and shortcuts to some sites.
"shortcuts on some local\network resources" have .lnk extension
"shortcuts to some sites" have .url extension
I've already found how to do this task separately
forfiles /p "%userprofile%\Desktop\folder" /s /m *.* /c "cmd /c for %G in (#path) do #if /I [%~xG] neq [.lnk] del /F /Q %G"
and
forfiles /p "%userprofile%\Desktop\folder" /s /m *.* /c "cmd /c for %G in (#path) do #if /I [%~xG] neq [.url] del /F /Q %G"
But how to combine these conditions into one string? Something like if /I [%~xG] neq [.lnk] AND [.lnk] ...
There's absolutely no need to use a for-loop within your forfiles /C command.
Try either;
ForFiles /P "%UserProfile%\Desktop\folder" /S /C "Cmd /C If /I Not #ext==\"lnk\" If /I Not #ext==\"url\" Del /A /F #path"
Or use the hex codes as shown in the help information, available at the Command Prompt by entering, forfiles /?
ForFiles /P "%UserProfile%\Desktop\folder" /S /C "Cmd /C If /I Not #ext==0x22lnk0x22 If /I Not #ext==0x22url0x22" Del /A /F #path"
I want to get the number of files modified before 10 days to a variable.
I can get number of files using
forfiles /P "D:\files" /S /D -10 | find /c /v ""
But when i try to assign it to a variable using FOR it gives error.
Command I used in FOR is
FOR /F "delims=" %i IN ('forfiles /P "D:\files" /S /D -10 | find /c /v ""') DO set today=%i
It actually works fine when I remove | find /c /v ""
FOR /F "delims=" %i IN ('forfiles /P "D:\files" /S /D -10 ^| find /c /v ""') DO set today=%i
in this case you need to escape the pipe.
Yes you can use the FIND command to count how many occurrences it finds but you don't need to. You could just use the set command to iterate a variable.
FOR /F "delims=" %%G IN ('forfiles /P "D:\files" /S /D -10') do #set /a count+=1