W.E.B
asked on
Batch to delete files based on date in File name
Good Day,
I have a folder in (C:\Users\Wassim\Desktop\D elete_Olde r_Invoices )
Files with date in the file name.
Examples
48-528277.20130515.txt
391-593063.20180216.csv
11582-593463.20170223.txt
1091-593132.20180223.csv
1077-592177.20180209.xls
4025-532154.20130915.xlsx
I'm looking for a batch that can Check the date in the file name and delete files older than x days.
Any help is appreciated.
I have a folder in (C:\Users\Wassim\Desktop\D
Files with date in the file name.
Examples
48-528277.20130515.txt
391-593063.20180216.csv
11582-593463.20170223.txt
1091-593132.20180223.csv
1077-592177.20180209.xls
4025-532154.20130915.xlsx
I'm looking for a batch that can Check the date in the file name and delete files older than x days.
Any help is appreciated.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Bill, of course that works, but isn't it a complicated way to first calculate Julian dates for each file? A string compare with yyyymmdd format of today - x days would work and is much easier to follow ;-).
ASKER
Thank you very much guys,
Can we limit this to only the 4 files types I have in the folder?
.txt
,csv
.xls
.xlsx
Thank you,
Can we limit this to only the 4 files types I have in the folder?
.txt
,csv
.xls
.xlsx
Thank you,
If those are the only file types in the folder then why "limit" it?
»bp
»bp
ASKER
I have some other file types in the same folder.
.pdf, .bak, .sql, .doc, .docx,...
.pdf, .bak, .sql, .doc, .docx,...
Updated BAT to filter extensions.
»bp
@echo off
setlocal EnableDelayedExpansion
REM Define base for folder, and days to keep old files
set BaseDir=C:\Users\Wassim\Desktop\Delete_Older_Invoices
set KeepDays=30
REM Get current date in YYYYMMDD format, convert to julian
set LocalDateTime=
for /f "tokens=* skip=1" %%A in ('wmic os get LocalDateTime') do (
if not defined LocalDateTime (
set LocalDateTime=%%A
)
)
REM Should never happen, but just be be extra safe
if not defined LocalDateTime exit /b
REM Convert current date to julian, suptract days to keep, convert cutoff back to YYYYMMDD gregorian
call :jDate jToday %LocalDateTime:~0,8%
set /a jKeepDate=jToday-KeepDays
call :gDate KeepDate %jKeepDate%
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir%\*-*.20??????..txt" "%BaseDir%\*-*.20??????..csv" "%BaseDir%\*-*.20??????..xls" "%BaseDir%\*-*.20??????..xlsx"') do (
set FileName=%%~nA
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Age:[!FileAge! days]
ECHO del "%BaseDir%\%%~A"
)
)
REM Done
exit /b
REM Subroutine to calculate julian date from (YYYYMMDD) date
:jDate [return-variable] [date-string]
set DateStr=%~2
set yy=%DateStr:~0,4%
set /A mm=1%DateStr:~4,2%-100
set /A dd=1%DateStr:~6,2%-100
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
set /a %~1=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
exit /b
REM Subroutine to calculate gregorian date in (YYYYMMDD) format from julian date
:gDate [return-variable] [date-string]
set /a L=%~2+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
set /a L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
set /a J=J+2-12*L,I=100*(N-49)+I+L
set /a YYYY=I,MM=100+J,DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
set %~1=%YYYY%%MM%%DD%
exit /b
»bp
$age = 30
$folder = 'C:\Temp\EE'
$dt = get-date (get-date).AddDays(-$age) -f 'yyyyMMdd'
get-childitem $folder\* -File |
? { $_.Extension -in '.txt', '.csv', '.xls', '.xlsx' } |
? { $dtFile = ($_.BaseName -split '\.')[-1]; $dtFile -like '2???????' -and $dtFile -le $dt } |
Remove-Item -WhatIf
ASKER
Good day,
Qlemo, the PowerShell is working fine.
Bill,
The script is not deleting the files. (I did remove the ECHO) ECHO del "%BaseDir%\%%~A"
Do I need to remove anything else?
Thanks again.
Qlemo, the PowerShell is working fine.
Bill,
The script is not deleting the files. (I did remove the ECHO) ECHO del "%BaseDir%\%%~A"
Do I need to remove anything else?
Thanks again.
No, that's all. When you ran it the first time, did it display any files that it would have deleted?
»bp
»bp
ASKER
Sorry Bill for not replying faster
I ran it form the command line, no files were listed.
I ran it form the command line, no files were listed.
Let me do a comprehensive test scenario here...
»bp
»bp
I see a/the problem. In a cut and paste I seem to have gotten double periods before the extensions. Change this statement:
»bp
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir%\*-*.20??????..txt" "%BaseDir%\*-*.20??????..csv" "%BaseDir%\*-*.20??????..xls" "%BaseDir%\*-*.20??????..xlsx"') do (
to:for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir%\*-*.20??????.txt" "%BaseDir%\*-*.20??????.csv" "%BaseDir%\*-*.20??????.xls" "%BaseDir%\*-*.20??????.xlsx"') do (
»bp
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much.
Welcome.
»bp
»bp
ASKER
Hi Bill,
Not sure if I still can ask a question.
I forgot to add one thing, I have a folder inside the directory as well
The batch doesn't seem to delete the files in it.
C:\Users\Wassim\Desktop\De lete_Older _Invoices\ Split reports\New Invoices
Much appreciated.
Not sure if I still can ask a question.
I forgot to add one thing, I have a folder inside the directory as well
The batch doesn't seem to delete the files in it.
C:\Users\Wassim\Desktop\De
Much appreciated.
That is correct, the BAT solution doesn't recurse into subfolders. So the question is do you want to recurse into all subfolders under the first level folders in the base folder, or only this one specific one? If just this specific one, then can it exist in other folders besides "Split Reports"?
If it is just one isolated other directory you want to clean then you could just add it in the code as follows. But if it can exist in other locations, or there are other "special case" we might want to change the code differently...
»bp
If it is just one isolated other directory you want to clean then you could just add it in the code as follows. But if it can exist in other locations, or there are other "special case" we might want to change the code differently...
@echo off
setlocal EnableDelayedExpansion
REM Define base for folder, and days to keep old files
set BaseDir=C:\Users\Wassim\Desktop\Delete_Older_Invoices
set BaseDir2=C:\Users\Wassim\Desktop\Delete_Older_Invoices\Split reports\New Invoices
set KeepDays=30
REM Get current date in YYYYMMDD format, convert to julian
set LocalDateTime=
for /f "tokens=* skip=1" %%A in ('wmic os get LocalDateTime') do (
if not defined LocalDateTime (
set LocalDateTime=%%A
)
)
REM Should never happen, but just be be extra safe
if not defined LocalDateTime exit /b
REM Convert current date to julian, suptract days to keep, convert cutoff back to YYYYMMDD gregorian
call :jDate jToday %LocalDateTime:~0,8%
set /a jKeepDate=jToday-KeepDays
call :gDate KeepDate %jKeepDate%
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir%\*-*.20??????.txt" "%BaseDir%\*-*.20??????.csv" "%BaseDir%\*-*.20??????.xls" "%BaseDir%\*-*.20??????.xlsx"') do (
set FileName=%%~nA
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
ECHO del "%BaseDir%\%%~A"
)
)
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir2%\*-*.20??????.txt" "%BaseDir2%\*-*.20??????.csv" "%BaseDir2%\*-*.20??????.xls" "%BaseDir2%\*-*.20??????.xlsx"') do (
set FileName=%%~nA
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
ECHO del "%BaseDir%\%%~A"
)
)
REM Done
exit /b
REM Subroutine to calculate julian date from (YYYYMMDD) date
:jDate [return-variable] [date-string]
set DateStr=%~2
set yy=%DateStr:~0,4%
set /A mm=1%DateStr:~4,2%-100
set /A dd=1%DateStr:~6,2%-100
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
set /a %~1=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
exit /b
REM Subroutine to calculate gregorian date in (YYYYMMDD) format from julian date
:gDate [return-variable] [date-string]
set /a L=%~2+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
set /a L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
set /a J=J+2-12*L,I=100*(N-49)+I+L
set /a YYYY=I,MM=100+J,DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
set %~1=%YYYY%%MM%%DD%
exit /b
»bp
ASKER
Hi Bill,
thank you very much, (it's working great)
I hate to be a pain,
but, what if the file was in the C Drive -- \Export Invoices
I tried to change the base Dir, but not deleting.
set BaseDir=C:\Program Files (x86)\EZSH 3.2
set BaseDir2=C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices
thank you
thank you very much, (it's working great)
I hate to be a pain,
but, what if the file was in the C Drive -- \Export Invoices
I tried to change the base Dir, but not deleting.
set BaseDir=C:\Program Files (x86)\EZSH 3.2
set BaseDir2=C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices
thank you
Typically you will need to have elevated privs to delete from program files folders, so you would need to launch the BAT file via "run as administrator".
»bp
»bp
ASKER
I tried to run it as Administrator,
when I try to list the files
I get error
\EZSH was unexpected at this time.
When I try t run the batch, nothing deletes.
when I try to list the files
I get error
\EZSH was unexpected at this time.
When I try t run the batch, nothing deletes.
when I try to list the files
I get error
\EZSH was unexpected at this time.
Do you mean just from a command line? If so you need quotes around the path since there are spaces in it, like:
DIR "C:\Program Files (x86)\EZSH 3.2"
(the BAT script always does this so it won't be a problem inside the script)»bp
ASKER
Thanks Bill for your time.
Still not deleting
set BaseDir=C:\Program Files (x86)\EZSH 3.2
set BaseDir2=C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices
Still not deleting
set BaseDir=C:\Program Files (x86)\EZSH 3.2
set BaseDir2=C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices
What does this command show at a command line?
»bp
dir "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.txt" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.csv" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xls" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xlsx"
»bp
ASKER
HI Bill
if I run
dir "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.txt" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.csv" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xls" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xlsx"
Directory of C:\Program Files (x86)\EZSH 3.2
File Not Found
Which is correct, I don't have any files
But, if I run this
dir "C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices\*-*.20??????.txt" "C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices\*-*.20??????.csv" "C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices\*-*.20??????.xls" "C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices\*-*.20??????.xlsx "
It lists all files to be deleted.
if I run
dir "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.txt" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.csv" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xls" "C:\Program Files (x86)\EZSH 3.2\*-*.20??????.xlsx"
Directory of C:\Program Files (x86)\EZSH 3.2
File Not Found
Which is correct, I don't have any files
But, if I run this
dir "C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoices\*-*.20??????.txt"
It lists all files to be deleted.
Odd. Okay, I added a little debug ECHO at the top of each file loop in the BAT below. It should display all files it finds that match the pattern in each folder, regardless of date stamp. See what this gives...
»bp
@echo off
setlocal EnableDelayedExpansion
REM Define base for folder, and days to keep old files
set "BaseDir=C:\Program Files (x86)\EZSH 3.2"
set "BaseDir2=C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoice"
set KeepDays=30
REM Get current date in YYYYMMDD format, convert to julian
set LocalDateTime=
for /f "tokens=* skip=1" %%A in ('wmic os get LocalDateTime') do (
if not defined LocalDateTime (
set LocalDateTime=%%A
)
)
REM Should never happen, but just be be extra safe
if not defined LocalDateTime exit /b
REM Convert current date to julian, suptract days to keep, convert cutoff back to YYYYMMDD gregorian
call :jDate jToday %LocalDateTime:~0,8%
set /a jKeepDate=jToday-KeepDays
call :gDate KeepDate %jKeepDate%
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir%\*-*.20??????.txt" "%BaseDir%\*-*.20??????.csv" "%BaseDir%\*-*.20??????.xls" "%BaseDir%\*-*.20??????.xlsx"') do (
set FileName=%%~nA
ECHO Checking file:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
ECHO del "%BaseDir%\%%~A"
)
)
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir2%\*-*.20??????.txt" "%BaseDir2%\*-*.20??????.csv" "%BaseDir2%\*-*.20??????.xls" "%BaseDir2%\*-*.20??????.xlsx"') do (
set FileName=%%~nA
ECHO Checking file:[%BaseDir2%\%%~A], Date:[!FileName:~-8!]
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
ECHO del "%BaseDir%\%%~A"
)
)
REM Done
exit /b
REM Subroutine to calculate julian date from (YYYYMMDD) date
:jDate [return-variable] [date-string]
set DateStr=%~2
set yy=%DateStr:~0,4%
set /A mm=1%DateStr:~4,2%-100
set /A dd=1%DateStr:~6,2%-100
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
set /a %~1=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
exit /b
REM Subroutine to calculate gregorian date in (YYYYMMDD) format from julian date
:gDate [return-variable] [date-string]
set /a L=%~2+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
set /a L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
set /a J=J+2-12*L,I=100*(N-49)+I+L
set /a YYYY=I,MM=100+J,DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
set %~1=%YYYY%%MM%%DD%
exit /b
»bp
ASKER
Sorry Bill,
still not deleting the files.
ECHO del "%BaseDir%\%%~A"
I removed the Echo,
still not deleting the files.
ECHO del "%BaseDir%\%%~A"
I removed the Echo,
Doh, I see it. When I/we added the BaseDir2 logic, I didn't change all the BaseDir references to BaseDir2. Existing code is shown below. Notice there are still some BaseDir references at the bottom, including the DEL statement. Change all those to be BaseDir2.
»bp
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%BaseDir2%\*-*.20??????.txt" "%BaseDir2%\*-*.20??????.csv" "%BaseDir2%\*-*.20??????.xls" "%BaseDir2%\*-*.20??????.xlsx"') do (
set FileName=%%~nA
ECHO Checking file:[%BaseDir2%\%%~A], Date:[!FileName:~-8!]
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:[%BaseDir%\%%~A], Date:[!FileName:~-8!]
ECHO del "%BaseDir%\%%~A"
)
)
»bp
ASKER
Sorry Bill,
still, nothing Deleted.
still, nothing Deleted.
Is anything ECHOing to the console when you run it?
»bp
»bp
ASKER
when I run the .bat you mean?
it runs so fast, I can't see what it's doing
it runs so fast, I can't see what it's doing
Are you running it from a CMD window, so that you can see the display after it ends? If not then do it that way, rather than just launching it from Explorer or the Run tool.
»bp
»bp
ASKER
I ran it from the command line
I see all the Exho
last few lines
C:\Users\Wassim>REM Process all files, delete if too old
\EZSH was unexpected at this time.
I see all the Exho
last few lines
C:\Users\Wassim>REM Process all files, delete if too old
\EZSH was unexpected at this time.
Okay, I figured out the problem, and while I was correcting that cleaned up the code a small amount. Now the folders to clean are a single list at the top, and we loop over that so that the logic isn't duplicated. Give this a try and see how it goes for you.
»bp
@echo off
setlocal EnableDelayedExpansion
REM Define base for folder, and days to keep old files
set BaseDirs="C:\Program Files (x86)\EZSH 3.2","C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoice"
set KeepDays=30
REM Get current date in YYYYMMDD format, convert to julian
set LocalDateTime=
for /f "tokens=* skip=1" %%A in ('wmic os get LocalDateTime') do (
if not defined LocalDateTime (
set LocalDateTime=%%A
)
)
REM Should never happen, but just be be extra safe
if not defined LocalDateTime exit /b
REM Convert current date to julian, suptract days to keep, convert cutoff back to YYYYMMDD gregorian
call :jDate jToday %LocalDateTime:~0,8%
set /a jKeepDate=jToday-KeepDays
call :gDate KeepDate %jKeepDate%
REM Process all folders we want to clean
for %%D in (%BaseDirs%) do (
REM Make sure this folder exists
if exist "%%~D\" (
REM Process all files, delete if too old
for /f "tokens=*" %%A in ('dir /a-d /b "%%~D\*-*.20??????.txt" "%%~D\*-*.20??????.csv" "%%~D\*-*.20??????.xls" "%%~D\*-*.20??????.xlsx"') do (
set FileName=%%~nA
ECHO Checking file:"%%~D\%%~A", Date:"!FileName:~-8!"
if !FileName:~-8! LSS %KeepDate% (
echo Removing File:"%%~D\%%~A", Date:"!FileName:~-8!"
ECHO del "%%~D\%%~A"
)
)
) else (
echo Missing folder:"%%~D"
)
)
REM Done
exit /b
REM Subroutine to calculate julian date from (YYYYMMDD) date
:jDate [return-variable] [date-string]
set DateStr=%~2
set yy=%DateStr:~0,4%
set /A mm=1%DateStr:~4,2%-100
set /A dd=1%DateStr:~6,2%-100
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
set /a %~1=dd-32075+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4
exit /b
REM Subroutine to calculate gregorian date in (YYYYMMDD) format from julian date
:gDate [return-variable] [date-string]
set /a L=%~2+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001
set /a L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11
set /a J=J+2-12*L,I=100*(N-49)+I+L
set /a YYYY=I,MM=100+J,DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
set %~1=%YYYY%%MM%%DD%
exit /b
»bp
ASKER
Fantastic.
Thank you very much.
Thank you very much.
Welcome, sorry to drag that out so much...
»bp
»bp
FWIW, using that list would work for the PowerShell code too:
$age = 30
$folder = "C:\Program Files (x86)\EZSH 3.2","C:\Program Files (x86)\EZSH 3.2\CSV Exporter\NEW CSV Exporter\Export Invoice"
$dt = get-date (get-date).AddDays(-$age) -f 'yyyyMMdd'
get-childitem $folder |
? { $dtFile = ($_.BaseName -split '\.')[-1]; $dtFile -like '2???????' -and $dtFile -le $dt } |
Remove-Item -WhatIf
That is, only the variable $folder needs to be changed from single value to array.
Q,
That's so long and wordy...
;-)
That's so long and wordy...
;-)
Oh, we can use aliases like gci and del to make it shorter :p.
Open in new window
»bp