File batch untuk menghapus file yang lebih lama dari N hari

678

Saya mencari cara untuk menghapus semua file yang lebih lama dari 7 hari dalam file batch. Saya telah mencari di seluruh web, dan menemukan beberapa contoh dengan ratusan baris kode, dan yang lainnya yang memerlukan menginstal utilitas baris perintah tambahan untuk menyelesaikan tugas.

Hal serupa dapat dilakukan dalam BASH hanya dalam beberapa baris kode. Tampaknya sesuatu yang paling tidak mudah dapat dilakukan untuk file batch di Windows. Saya mencari solusi yang bekerja di command prompt standar Windows, tanpa utilitas tambahan. Harap tidak ada PowerShell atau Cygwin.

Kibbee
sumber
8
Jeff Atwood menjawab ini di Serverfault yang menurut saya harus didokumentasikan di sini. serverfault.com/questions/49614/delete-files-older-than-x-days
Dusty
Metode baru yang didasarkan pada file .BAT yang menggunakan perintah CMD.EXE internal hanya telah diposting di sini: stackoverflow.com/questions/9746778/…
Aacini
1
gehrcke.de/timegaps telah dirancang untuk tujuan ini. Bahkan memungkinkan untuk skema penghapusan yang lebih canggih: selain menyimpan file dari 7 hari terakhir, itu juga memungkinkan untuk menyimpan satu file untuk masing-masing 8 minggu, 12, bulan, 2 tahun terakhir.
Dr. Jan-Philip Gehrcke

Jawaban:

1071

Nikmati:

forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"

Lihat forfilesdokumentasi untuk lebih jelasnya.

Untuk lebih banyak barang, lihat Indeks AZ pada baris perintah Windows XP .

Jika Anda belum forfilesmenginstal pada mesin Anda, salin dari Windows Server 2003 ke mesin Windows XP di %WinDir%\system32\. Ini dimungkinkan karena EXE sepenuhnya kompatibel antara Windows Server 2003 dan Windows XP.

Versi Windows dan Windows Server yang lebih baru telah menginstalnya secara default.

Untuk Windows 7 dan yang lebih baru (termasuk Windows 10):

Sintaksnya sedikit berubah. Oleh karena itu perintah yang diperbarui adalah:

forfiles /p "C:\what\ever" /s /m *.* /D -<number of days> /C "cmd /c del @path"
aku
sumber
12
Harus del @FILE, kasus penting Juga saya sarankan menggunakan / c gema @FILE untuk pengujian
Russell Steen
40
@Russell: @PATH adalah path lengkap, termasuk nama. @FILE hanyalah nama, jadi jika Anda berurusan dengan subfolder, @fd tidak akan berfungsi.
gregmac
86
Perhatikan bahwa jika Anda ingin file TUA dari 10 hari, Anda perlu menentukan -d "-10". -ve berarti "lebih tua dari", + ve berarti "lebih baru dari". Anda juga dapat menentukan format DDMMYY atau -DDMMYY sebagai parameter ke -d.
gregmac
42
Saya menggunakan sintaks ini pada Win Server 2008: forfiles / P "C: \ Mysql_backup" / S / M * .sql / D -30 / C "cmd / c del @PATH"
jman
9
Jawaban ini berfungsi ketika "lebih dari 7 hari" didefinisikan sebagai "dimodifikasi lebih dari 7 hari yang lalu" daripada "dibuat lebih dari 7 hari yang lalu". Bagaimana yang terakhir dapat dicapai?
TimS
76

Jalankan perintah berikut :

ROBOCOPY C:\source C:\destination /mov /minage:7
del C:\destination /q

Pindahkan semua file (menggunakan / mov, yang memindahkan file dan kemudian menghapusnya sebagai lawan dari / memindahkan yang memindahkan seluruh file yang kemudian dihapus) melalui robocopy ke lokasi lain, dan kemudian jalankan perintah delete pada path itu dan Anda semua baik.

Juga jika Anda memiliki direktori dengan banyak data di dalamnya Anda dapat menggunakan /mirsakelar

Iman
sumber
5
Sebagian besar, ini adalah jawaban yang cukup tidak praktis. Jika saya memiliki direktori dengan banyak data di dalamnya, tidak akan berfungsi dengan baik. Saya akan memilih salah satu jawaban yang membuatnya "di tempat"
adamb0mb
5
@ adamb0mb ini sama sekali tidak praktis - jika "tujuan" berada di sistem file yang sama dengan "sumber" , operasi perpindahannya cukup ringan. Karena robocopy benar - benar kuat, itu sebenarnya akan bekerja untuk ukuran direktori apa pun, nama file yang tidak jelas, pada dasarnya panjang jalur arbitrer dan termasuk direktori jika Anda memerlukannya - sesuatu yang pasti tidak dapat dikatakan tentang banyak utilitas Windows lainnya. Saya akan menggunakan rd /s /q c:\destinationalih-alih delperintah meskipun atau bahkan menggunakan robocopy /mir c:\emptydir c:\destinationmenjalankan lain untuk mengosongkan direktori jika Anda mengharapkan masalah dengan nama file.
syneticon-dj
12
Plus, robocopy mendukung jalur UNC - yang forfilesdari jawaban yang diterima tidak akan berhasil.
syneticon-dj
3
Pikiranku lebih sesuai: "File-file saya sudah di tempat yang saya inginkan. Saya tidak mau harus memindahkannya." "Menghapus file secara logis adalah apa yang Anda lakukan, jadi lakukan itu. Jangan membebani Robocopy untuk melakukannya"
adamb0mb
3
Saya merekomendasikan ini satu-liner untuk melihat semua file dalam C:\testlebih dari 7 hari. Untuk menghapus file, ubah echoke del:forfiles /p "C:\test" /m "*.*" /c "cmd /c echo @file" /D -7
PowerUser
25

Ok bosan sedikit dan muncul dengan ini, yang berisi versi saya tentang penggantian zaman Linux orang miskin terbatas untuk penggunaan sehari-hari (tidak ada waktu retensi):

7daysclean.cmd

@echo off
setlocal ENABLEDELAYEDEXPANSION
set day=86400
set /a year=day*365
set /a strip=day*7
set dSource=C:\temp

call :epoch %date%
set /a slice=epoch-strip

for /f "delims=" %%f in ('dir /a-d-h-s /b /s %dSource%') do (
    call :epoch %%~tf
    if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)
)
exit /b 0

rem Args[1]: Year-Month-Day
:epoch
    setlocal ENABLEDELAYEDEXPANSION
    for /f "tokens=1,2,3 delims=-" %%d in ('echo %1') do set Years=%%d& set Months=%%e& set Days=%%f
    if "!Months:~0,1!"=="0" set Months=!Months:~1,1!
    if "!Days:~0,1!"=="0" set Days=!Days:~1,1!
    set /a Days=Days*day
    set /a _months=0
    set i=1&& for %%m in (31 28 31 30 31 30 31 31 30 31 30 31) do if !i! LSS !Months! (set /a _months=!_months! + %%m*day&& set /a i+=1)
    set /a Months=!_months!
    set /a Years=(Years-1970)*year
    set /a Epoch=Years+Months+Days
    endlocal& set Epoch=%Epoch%
    exit /b 0

PEMAKAIAN

set /a strip=day*7: Ubah 7 untuk jumlah hari yang akan disimpan.

set dSource=C:\temp : Ini adalah direktori awal untuk memeriksa file.

CATATAN

Ini adalah kode non-destruktif, itu akan menampilkan apa yang akan terjadi.

Ubah:

if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)

untuk sesuatu seperti:

if !epoch! LEQ %slice% del /f %%f

jadi file sebenarnya bisa dihapus

Februari : hard-coded menjadi 28 hari. Tahun-tahun Bissextile adalah neraka untuk ditambahkan, sungguh. jika seseorang memiliki ide yang tidak akan menambahkan 10 baris kode, silakan dan posting jadi saya menambahkannya ke kode saya.

zaman : Saya tidak mempertimbangkan, karena kebutuhan untuk menghapus file yang lebih tua dari tanggal tertentu, mengambil jam / menit akan menghapus file dari hari yang dimaksudkan untuk disimpan.

BATASAN

zaman menerima begitu saja format tanggal pendek Anda adalah YYYY-MM-DD. Ini perlu disesuaikan untuk pengaturan lain atau evaluasi run-time (baca sShortTime, konfigurasi yang terikat pengguna, konfigurasikan urutan bidang yang tepat dalam filter dan gunakan filter untuk mengekstrak data yang benar dari argumen).

Apakah saya menyebutkan saya benci formating otomatis editor ini? menghapus garis kosong dan copy-paste adalah neraka.

Saya harap ini membantu.

Jay
sumber
4
+1 untuk kode non-destruktif, saya akan mencoba dan mengingatnya ketika saya memberikan contoh kode sendiri.
Haugholt
5
Jauh terlambat dan sama sekali tidak berhubungan, tetapi 7daysclean.cmdterdengar seperti nama yang luar biasa untuk band Synth-Punk.
Flonk
21
forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"

Anda harus melakukannya /d -3(3 hari sebelumnya) Ini berfungsi dengan baik untuk saya. Jadi semua kumpulan rumit bisa berada di tempat sampah. Juga forfilestidak mendukung jalur UNC, jadi buat koneksi jaringan ke drive tertentu.

Arno Jansen
sumber
3
Kesalahan yang sama seperti pada jawaban lain (termasuk yang diterima). Dari mana kebiasaan aneh untuk menentukan ini *.*berasal? Wildcard *.*tidak cocok dengan semua file di Windows. Itu hanya cocok dengan file dengan .nama mereka. OP tidak pernah mengatakan apa-apa tentang keharusan .dalam nama file. Parameter yang tepat adalah /M *, tetapi ini adalah standarnya. Tidak perlu /Msama sekali.
AnT
@AnT: Apakah Anda yakin? Saya pikir *.*berperilaku persis seperti *di Windows. Bahkan, saya baru mencobanya di komputer saya, dan dir *.*memang terdaftar test file, file tanpa ekstensi.
Andreas Rejbrand
1
@Andreas Rejbrand: Saya menemukan itu mengejutkan juga, tetapi pengobatan *.*tidak konsisten antara, katakanlah, dirdan -mopsi forfiles. The -m *.*mask memang akan melewatkan nama file extensionless, seperti yang saya nyatakan dalam komentar saya di atas (mencobanya sendiri). Bagian yang lucu di sini adalah bahwa dokumentasi MS secara eksplisit menyatakan itu -m *.*adalah default. Namun, jika Anda mencobanya dalam kehidupan nyata, Anda akan melihat bahwa default-nya sebenarnya -m *- semua file diulang.
AnT
1
Halaman dokumentasi MS ini - technet.microsoft.com/en-us/library/cc753551(v=ws.11).aspx - berisi sejumlah besar kesalahan (misalnya dalam contoh) karena penulis dokumen salah percaya bahwa *.*topeng diterapkan ke semua file. Pertanyaan retoris saya tentang "kebiasaan aneh ini" memang tidak masuk akal, karena memperlakukan *.*dan *setara adalah konvensi lama Windows. Namun, /mopsi dalam forfileskebetulan melanggar konvensi itu untuk beberapa alasan.
AnT
1
Latar Belakang pada 5 wildcard pada Windows: blogs.msdn.microsoft.com/jeremykuhne/2017/06/04/...
MSalters
18

Lihat jawaban saya untuk pertanyaan serupa :

REM del_old.bat
REM usage: del_old MM-DD-YYY
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do if exist %%~nxa echo %%~nxa >> FILES_TO_KEEP.TXT
for /f "tokens=*" %%a IN ('xcopy *.* /L /I /EXCLUDE:FILES_TO_KEEP.TXT null') do if exist "%%~nxa" del "%%~nxa"

Ini menghapus file yang lebih lama dari tanggal yang ditentukan. Saya yakin ini dapat dimodifikasi untuk kembali tujuh hari dari tanggal saat ini.

pembaruan: Saya perhatikan bahwa HerbCSO telah meningkat pada skrip di atas. Saya sarankan menggunakan versinya .

e.James
sumber
12

Perintah saya adalah

forfiles -p "d:\logs" -s -m*.log -d-15 -c"cmd /c del @PATH\@FILE" 

@PATH - hanya jalan dalam kasus saya, jadi saya harus menggunakan @PATH\@FILE

juga forfiles /?tidak bekerja untuk saya juga, tetapi forfiles(tanpa "?") berfungsi dengan baik.

Dan satu-satunya pertanyaan yang saya miliki: bagaimana cara menambahkan banyak topeng (misalnya " .log | .bak")?

Semua ini mengenai forfiles.exe yang saya unduh di sini (pada win XP)

Tetapi jika Anda menggunakan server Windows forfiles.exe harus sudah ada dan berbeda dari versi ftp. Itu sebabnya saya harus memodifikasi perintah.

Untuk Windows Server 2003 saya menggunakan perintah ini:

forfiles -p "d:\Backup" -s -m *.log -d -15 -c "cmd /c del @PATH"
segero
sumber
9

Sering ada pertanyaan terkait tanggal / waktu relatif untuk diselesaikan dengan file batch. Tetapi interpreter command line cmd.exe tidak memiliki fungsi untuk perhitungan tanggal / waktu. Banyak solusi yang berfungsi baik menggunakan aplikasi konsol tambahan atau skrip telah diposting di sini, di halaman lain dari Stack Overflow dan di situs web lain.

Umum untuk operasi berdasarkan tanggal / waktu adalah persyaratan untuk mengubah string tanggal / waktu menjadi detik sejak hari yang ditentukan. Sangat umum adalah 1970-01-01 00:00:00 UTC. Tetapi hari berikutnya dapat juga digunakan tergantung pada rentang tanggal yang diperlukan untuk mendukung tugas tertentu.

Jay memposting 7daysclean.cmd yang berisi solusi cepat "date to seconds" untuk penerjemah baris perintah cmd.exe . Tapi itu tidak mengambil tahun kabisat diperhitungkan. JR memposting add-on untuk memperhitungkan hari kabisat di tahun berjalan, tetapi mengabaikan tahun kabisat lainnya sejak tahun dasar, yaitu sejak tahun 1970.

Saya menggunakan sejak 20 tahun tabel statis (array) dibuat sekali dengan fungsi C kecil untuk dengan cepat mendapatkan jumlah hari termasuk hari kabisat dari 1970-01-01 dalam fungsi konversi tanggal / waktu dalam aplikasi saya yang ditulis dalam C / C ++.

Metode tabel yang sangat cepat ini dapat digunakan juga dalam kode batch menggunakan perintah FOR . Jadi saya memutuskan untuk membuat kode subrutin batch GetSecondsyang menghitung jumlah detik sejak 1970-01-01 00:00:00 UTC untuk string tanggal / waktu yang diteruskan ke rutin ini.

Catatan: Kabisat detik tidak diperhitungkan karena sistem file Windows juga tidak mendukung detik kabisat.

Pertama, tabel:

  1. Hari sejak 1970-01-01 00:00:00 UTC untuk setiap tahun termasuk hari kabisat.

    1970 - 1979:     0   365   730  1096  1461  1826  2191  2557  2922  3287
    1980 - 1989:  3652  4018  4383  4748  5113  5479  5844  6209  6574  6940
    1990 - 1999:  7305  7670  8035  8401  8766  9131  9496  9862 10227 10592
    2000 - 2009: 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245
    2010 - 2019: 14610 14975 15340 15706 16071 16436 16801 17167 17532 17897
    2020 - 2029: 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550
    2030 - 2039: 21915 22280 22645 23011 23376 23741 24106 24472 24837 25202
    2040 - 2049: 25567 25933 26298 26663 27028 27394 27759 28124 28489 28855
    2050 - 2059: 29220 29585 29950 30316 30681 31046 31411 31777 32142 32507
    2060 - 2069: 32872 33238 33603 33968 34333 34699 35064 35429 35794 36160
    2070 - 2079: 36525 36890 37255 37621 37986 38351 38716 39082 39447 39812
    2080 - 2089: 40177 40543 40908 41273 41638 42004 42369 42734 43099 43465
    2090 - 2099: 43830 44195 44560 44926 45291 45656 46021 46387 46752 47117
    2100 - 2106: 47482 47847 48212 48577 48942 49308 49673
    

    Menghitung detik untuk tahun 2039 hingga 2106 dengan zaman mulai 1970-01-01 hanya mungkin dengan menggunakan variabel 32-bit yang tidak ditandai, yaitu panjang yang tidak ditandatangani (atau int tidak ditandatangani) di C / C ++.

    Tapi cmd.exe digunakan untuk ekspresi matematika, variabel 32-bit yang ditandatangani. Oleh karena itu nilai maksimum adalah 2147483647 (0x7FFFFFFF) yaitu 2038-01-19 03:14:07.

  2. Informasi tahun kabisat (Tidak / Ya) untuk tahun 1970 hingga 2106.

    1970 - 1989: N N Y N N N Y N N N Y N N N Y N N N Y N
    1990 - 2009: N N Y N N N Y N N N Y N N N Y N N N Y N
    2010 - 2029: N N Y N N N Y N N N Y N N N Y N N N Y N
    2030 - 2049: N N Y N N N Y N N N Y N N N Y N N N Y N
    2050 - 2069: N N Y N N N Y N N N Y N N N Y N N N Y N
    2070 - 2089: N N Y N N N Y N N N Y N N N Y N N N Y N
    2090 - 2106: N N Y N N N Y N N N N N N N Y N N
                                     ^ year 2100
    
  3. Jumlah hari hingga hari pertama setiap bulan pada tahun berjalan.

                       Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
    Year with 365 days:  0  31  59  90 120 151 181 212 243 273 304 334
    Year with 366 days:  0  31  60  91 121 152 182 213 244 274 305 335
    

Mengonversi tanggal ke jumlah detik sejak 1970-01-01 cukup mudah menggunakan tabel tersebut.

Tolong perhatiannya!

Format string tanggal dan waktu tergantung pada pengaturan wilayah dan bahasa Windows. Pembatas dan urutan token yang ditetapkan ke variabel lingkungan Day, Monthdan Yearpada loop FOR pertama GetSecondsharus disesuaikan dengan format tanggal / waktu lokal jika perlu.

Diperlukan untuk mengadaptasi string tanggal dari variabel lingkungan jika format tanggal dalam variabel lingkungan DATE berbeda dengan format tanggal yang digunakan oleh perintah FOR pada %%~tF.

Misalnya ketika %DATE%mengembang ke Sun 02/08/2015sementara %%~tFmengembang ke 02/08/2015 07:38 PMkode di bawah ini dapat digunakan dengan memodifikasi baris 4 ke:

call :GetSeconds "%DATE:~4% %TIME%"

Ini menghasilkan passing ke subrutin saja 02/08/2015- string tanggal tanpa 3 huruf singkatan hari kerja dan karakter spasi yang terpisah.

Sebagai alternatif, berikut dapat digunakan untuk melewati tanggal saat ini dalam format yang benar:

call :GetSeconds "%DATE:~-10% %TIME%"

Sekarang 10 karakter terakhir dari string tanggal diteruskan ke fungsi GetSecondsdan oleh karena itu tidak masalah jika string tanggal dari variabel lingkungan DATE adalah dengan atau tanpa hari kerja selama hari dan bulan selalu dengan 2 digit dalam urutan yang diharapkan, yaitu dalam format dd/mm/yyyy atau dd.mm.yyyy.

Berikut ini adalah kode batch dengan menjelaskan komentar yang hanya menampilkan file mana yang akan dihapus dan file mana yang harus disimpan dalam C:\Tempfolder tree, lihat kode loop FOR pertama .

@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Get seconds since 1970-01-01 for current date and time.
call :GetSeconds "%DATE% %TIME%"
rem Subtract seconds for 7 days from seconds value.
set /A "LastWeek=Seconds-7*86400"

rem For each file in each subdirectory of C:\Temp get last modification date
rem (without seconds -> append second 0) and determine the number of seconds
rem since 1970-01-01 for this date/time. The file can be deleted if seconds
rem value is lower than the value calculated above.

for /F "delims=" %%F in ('dir /A-D-H-S /B /S "C:\Temp"') do (
    call :GetSeconds "%%~tF:0"
    rem if !Seconds! LSS %LastWeek% del /F "%%~fF"
    if !Seconds! LEQ %LastWeek% (
        echo Delete "%%~fF"
    ) else (
        echo Keep   "%%~fF"
    )
)
endlocal
goto :EOF


rem No validation is made for best performance. So make sure that date
rem and hour in string is in a format supported by the code below like
rem MM/DD/YYYY hh:mm:ss or M/D/YYYY h:m:s for English US date/time.

:GetSeconds

rem If there is " AM" or " PM" in time string because of using 12 hour
rem time format, remove those 2 strings and in case of " PM" remember
rem that 12 hours must be added to the hour depending on hour value.

set "DateTime=%~1"
set "Add12Hours=0"
if "%DateTime: AM=%" NEQ "%DateTime%" (
    set "DateTime=%DateTime: AM=%"
) else if "%DateTime: PM=%" NEQ "%DateTime%" (
    set "DateTime=%DateTime: PM=%"
    set "Add12Hours=1"
)

rem Get year, month, day, hour, minute and second from first parameter.

for /F "tokens=1-6 delims=,-./: " %%A in ("%DateTime%") do (
    rem For English US date MM/DD/YYYY or M/D/YYYY
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY
    rem set "Day=%%A" & set "Month=%%B" & set "Year=%%C"
    set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F"
)
rem echo Date/time is: %Year%-%Month%-%Day% %Hour%:%Minute%:%Second%

rem Remove leading zeros from the date/time values or calculation could be wrong.
if "%Month:~0,1%"  EQU "0" ( if "%Month:~1%"  NEQ "" set "Month=%Month:~1%"   )
if "%Day:~0,1%"    EQU "0" ( if "%Day:~1%"    NEQ "" set "Day=%Day:~1%"       )
if "%Hour:~0,1%"   EQU "0" ( if "%Hour:~1%"   NEQ "" set "Hour=%Hour:~1%"     )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" )

rem Add 12 hours for time range 01:00:00 PM to 11:59:59 PM,
rem but keep the hour as is for 12:00:00 PM to 12:59:59 PM.
if "%Add12Hours%" == "1" (
    if %Hour% LSS 12 set /A Hour+=12
)
set "DateTime="
set "Add12Hours="

rem Must use 2 arrays as more than 31 tokens are not supported
rem by command line interpreter cmd.exe respectively command FOR.
set /A "Index1=Year-1979"
set /A "Index2=Index1-30"

if %Index1% LEQ 30 (
    rem Get number of days to year for the years 1980 to 2009.
    for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y"
    for /F "tokens=%Index1% delims= " %%L in ("Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N") do set "LeapYear=%%L"
) else (
    rem Get number of days to year for the years 2010 to 2038.
    for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y"
    for /F "tokens=%Index2% delims= " %%L in ("N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N") do set "LeapYear=%%L"
)

rem Add the days to month in year.
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)

rem Add the complete days in month of year.
set /A "Days+=Day-1"

rem Calculate the seconds which is easy now.
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"

rem Exit this subroutine
goto :EOF

Untuk kinerja yang optimal, sebaiknya hapus semua komentar, yaitu semua baris yang dimulai dengan rem setelah 0-4 spasi.

Dan array dapat dibuat juga lebih kecil, yaitu mengurangi rentang waktu dari 1980-01-01 00:00:00 menjadi 2038-01-19 03:14:07 seperti yang saat ini didukung oleh kode batch di atas misalnya ke 2015-01 -01 hingga 2019-12-31 sebagai kode di bawah ini menggunakan yang benar-benar menghapus file yang lebih lama dari 7 hari di C:\Tempfolder tree.

Selanjutnya kode batch di bawah ini dioptimalkan untuk format waktu 24 jam.

@echo off
setlocal EnableDelayedExpansion
call :GetSeconds "%DATE:~-10% %TIME%"
set /A "LastWeek=Seconds-7*86400"

for /F "delims=" %%F in ('dir /A-D-H-S /B /S "C:\Temp"') do (
    call :GetSeconds "%%~tF:0"
    if !Seconds! LSS %LastWeek% del /F "%%~fF"
)
endlocal
goto :EOF

:GetSeconds
for /F "tokens=1-6 delims=,-./: " %%A in ("%~1") do (
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F"
)
if "%Month:~0,1%"  EQU "0" ( if "%Month:~1%"  NEQ "" set "Month=%Month:~1%"   )
if "%Day:~0,1%"    EQU "0" ( if "%Day:~1%"    NEQ "" set "Day=%Day:~1%"       )
if "%Hour:~0,1%"   EQU "0" ( if "%Hour:~1%"   NEQ "" set "Hour=%Hour:~1%"     )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" )
set /A "Index=Year-2014"
for /F "tokens=%Index% delims= " %%Y in ("16436 16801 17167 17532 17897") do set "Days=%%Y"
for /F "tokens=%Index% delims= " %%L in ("N Y N N N") do set "LeapYear=%%L"
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)
set /A "Days+=Day-1"
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"
goto :EOF

Untuk informasi lebih lanjut tentang format tanggal dan waktu dan perbandingan waktu file di Windows lihat jawaban saya di Cari tahu apakah file lebih dari 4 jam dalam file batch dengan banyak informasi tambahan tentang waktu file.

Mofi
sumber
9

Salin kode ini dan simpan sebagai DelOldFiles.vbs.

PENGGUNAAN CMD: cscript //nologo DelOldFiles.vbs 15

15 berarti menghapus file yang lebih lama dari 15 hari yang lalu.

  'copy from here
    Function DeleteOlderFiles(whichfolder)
       Dim fso, f, f1, fc, n, ThresholdDate
       Set fso = CreateObject("Scripting.FileSystemObject")
       Set f = fso.GetFolder(whichfolder)
       Set fc = f.Files
       Set objArgs = WScript.Arguments
       n = 0
       If objArgs.Count=0 Then
           howmuchdaysinpast = 0
       Else
           howmuchdaysinpast = -objArgs(0)
       End If
       ThresholdDate = DateAdd("d", howmuchdaysinpast, Date)   
       For Each f1 in fc
     If f1.DateLastModified<ThresholdDate Then
        Wscript.StdOut.WriteLine f1
        f1.Delete
        n = n + 1    
     End If
       Next
       Wscript.StdOut.WriteLine "Deleted " & n & " file(s)."
    End Function

    If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
      WScript.Echo "USAGE ONLY IN COMMAND PROMPT: cscript DelOldFiles.vbs 15" & vbCrLf & "15 means to delete files older than 15 days in past."
      WScript.Quit 0   
    End If

    DeleteOlderFiles(".")
 'to here
Paris
sumber
8

Untuk Windows Server 2008 R2:

forfiles /P c:\sql_backups\ /S /M *.sql /D -90 /C "cmd /c del @PATH"

Ini akan menghapus semua file .sql yang lebih lama dari 90 hari.

NotJustClarkKent
sumber
7

Gunakan forfiles.

Ada beberapa versi berbeda. Yang awal menggunakan parameter gaya unix.

Versi saya (untuk server 2000 - perhatikan tidak ada ruang setelah switch) -

forfiles -p"C:\what\ever" -s -m*.* -d<number of days> -c"cmd /c del @path"

Untuk menambahkan forfile ke XP, dapatkan exe dari ftp://ftp.microsoft.com/ResKit/y2kfix/x86/

dan menambahkannya ke C: \ WINDOWS \ system32

Aidan Ewen
sumber
11
@ Kibbee itu bukan jawaban yang sama dengan sintaks yang berbeda. Ini adalah upaya geniune untuk membantu. Dikenal sangat sedikit dari baris perintah windows, saya menghabiskan berjam-jam frustrasi membuat ini berfungsi. Bit kunci info bagi saya adalah kenyataan bahwa ada versi yang berbeda (dengan sintaks yang berbeda), dan bahwa saya perlu menghapus spasi. Tak satu pun dari hal-hal ini dimasukkan dalam jawaban asli. (Saya akan mengomentari jawabannya tetapi saya tidak memiliki hak istimewa
Aidan Ewen
Kesalahan yang sama seperti pada jawaban lain (termasuk yang diterima). Wildcard *.*in forfilestidak cocok dengan semua file. Ini hanya cocok dengan file .dalam namanya (yaitu file dengan ekstensi). OP tidak pernah mengatakan apa-apa tentang keharusan .dalam nama file. Parameter yang tepat adalah /M *, tetapi ini adalah standarnya. Tidak perlu /Msama sekali.
AnT
7

Untuk windows 2012 R2 berikut ini akan berfungsi:

    forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c del @path"

untuk melihat file yang akan dihapus gunakan ini

    forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c echo @path @fdate"
Viktor Ka
sumber
Ini bahkan berfungsi di Windows Server 2008 dan di atasnya dan Windows 7.
kwrl
6

IMO, JavaScript berangsur-angsur menjadi standar skrip universal: mungkin tersedia di lebih banyak produk daripada bahasa skrip lain (di Windows, itu tersedia menggunakan Host Scripting Windows). Saya harus membersihkan file lama di banyak folder, jadi di sini adalah fungsi JavaScript untuk melakukannya:

// run from an administrator command prompt (or from task scheduler with full rights):  wscript jscript.js
// debug with:   wscript /d /x jscript.js

var fs = WScript.CreateObject("Scripting.FileSystemObject");

clearFolder('C:\\temp\\cleanup');

function clearFolder(folderPath)
{
    // calculate date 3 days ago
    var dateNow = new Date();
    var dateTest = new Date();
    dateTest.setDate(dateNow.getDate() - 3);

    var folder = fs.GetFolder(folderPath);
    var files = folder.Files;

    for( var it = new Enumerator(files); !it.atEnd(); it.moveNext() )
    {
        var file = it.item();

        if( file.DateLastModified < dateTest)
        {
            var filename = file.name;
            var ext = filename.split('.').pop().toLowerCase();

            if (ext != 'exe' && ext != 'dll')
            {
                file.Delete(true);
            }
        }
    }

    var subfolders = new Enumerator(folder.SubFolders);
    for (; !subfolders.atEnd(); subfolders.moveNext())
    {
        clearFolder(subfolders.item().Path);
    }
}

Agar setiap folder dihapus, cukup tambahkan panggilan lain ke fungsi clearFolder (). Kode khusus ini juga memelihara file exe dan dll, dan membersihkan subfolder juga.

Graham Laight
sumber
6

Bagaimana dengan modifikasi ini pada 7daysclean.cmd untuk mengambil satu tahun kabisat?

Ini dapat dilakukan dalam waktu kurang dari 10 baris kode!

set /a Leap=0
if (Month GEQ 2 and ((Years%4 EQL 0 and Years%100 NEQ 0) or Years%400 EQL 0)) set /a Leap=day
set /a Months=!_months!+Leap

Edit oleh Mofi:

Kondisi di atas yang dikontribusikan oleh JR selalu bernilai false karena sintaks yang tidak valid.

Dan Month GEQ 2juga salah karena menambahkan 86400 detik untuk satu hari lagi harus dilakukan dalam satu tahun kabisat hanya untuk bulan Maret hingga Desember, tetapi tidak untuk Februari.

Kode kerja untuk memperhitungkan hari kabisat - hanya tahun ini - dalam file batch 7daysclean.cmd yang diposting oleh Jay adalah:

set "LeapDaySecs=0"
if %Month% LEQ 2 goto CalcMonths
set /a "LeapRule=Years%%4"
if %LeapRule% NEQ 0 goto CalcMonths
rem The other 2 rules can be ignored up to year 2100.
set /A "LeapDaySecs=day"
:CalcMonths
set /a Months=!_months!+LeapDaySecs
JR
sumber
5

Mungkin saya menambahkan kontribusi sederhana ke utas yang sudah berharga ini. Saya menemukan bahwa solusi lain mungkin menghilangkan teks kesalahan aktual tetapi mengabaikan% ERRORLEVEL% yang menandakan kegagalan dalam aplikasi saya. DAN saya ingin secara sah% ERRORLEVEL% selama itu bukan kesalahan "Tidak ada file yang ditemukan".

Beberapa contoh:

Khusus debugging dan menghilangkan kesalahan:

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||echo found success

Menggunakan oneliner untuk mengembalikan keberhasilan atau kegagalan ERRORLEVEL:

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT /B 1||EXIT /B 0

Menggunakan oneliner untuk menjaga ERRORLEVEL nol untuk sukses dalam konteks batchfile di tengah-tengah kode lain (ver> nul me-reset ERRORLEVEL):

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||ver > nul

Untuk langkah pekerjaan SQL Server Agent CmdExec saya mendarat di berikut ini. Saya tidak tahu apakah ini bug, tetapi CmdExec dalam langkah ini hanya mengenali baris kode pertama:

cmd /e:on /c "forfiles /p "C:\SQLADMIN\MAINTREPORTS\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT 1||EXIT 0"&exit %errorlevel%
Menyengat
sumber
5

Astaga, sudah banyak jawaban. Rute sederhana dan nyaman yang saya temukan adalah untuk mengeksekusi ROBOCOPY.EXE dua kali secara berurutan dari satu instruksi baris perintah Windows menggunakan parameter & .

ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 & ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 /PURGE

Dalam contoh ini berfungsi dengan memilih semua file ( . ) Yang lebih tua dari 30 hari dan memindahkannya ke folder target. Perintah kedua melakukan hal yang sama lagi dengan penambahan perintah PURGE yang berarti menghapus file di folder target yang tidak ada di folder sumber. Jadi intinya, perintah pertama MOVES file dan DELETES kedua karena mereka tidak ada lagi di folder sumber ketika perintah kedua dipanggil.

Lihat dokumentasi ROBOCOPY dan gunakan sakelar / L saat menguji.

GBGOLC
sumber
4

Jika Anda memiliki kit sumber daya XP, Anda dapat menggunakan robocopy untuk memindahkan semua direktori lama ke satu direktori, lalu gunakan rmdir untuk menghapus satu saja:

mkdir c:\temp\OldDirectoriesGoHere
robocopy c:\logs\SoManyDirectoriesToDelete\ c:\temp\OldDirectoriesGoHere\ /move /minage:7
rmdir /s /q c:\temp\OldDirectoriesGoHere
neuracnu
sumber
4

Saya pikir jawaban e.James baik karena ia bekerja dengan versi Windows yang tidak dimodifikasi sedini Windows 2000 SP4 (dan mungkin sebelumnya), tetapi diperlukan penulisan ke file eksternal. Berikut ini adalah versi yang dimodifikasi yang tidak membuat file teks eksternal sambil mempertahankan kompatibilitas:

REM del_old.cmd
REM usage: del_old MM-DD-YYYY
setlocal enabledelayedexpansion
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)

Agar benar dengan pertanyaan awal, ini ada dalam skrip yang melakukan SEMUA matematika untuk Anda jika Anda menyebutnya dengan jumlah hari sebagai parameter:

REM del_old_compute.cmd
REM usage: del_old_compute N
setlocal enabledelayedexpansion
set /a days=%1&set cur_y=%DATE:~10,4%&set cur_m=%DATE:~4,2%&set cur_d=%DATE:~7,2%
for /f "tokens=1 delims==" %%a in ('set cur_') do if "!%%a:~0,1!"=="0" set /a %%a=!%%a:~1,1!+0
set mo_2=28&set /a leapyear=cur_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
set mo_1=31&set mo_3=31&set mo_4=30&set mo_5=31
set mo_6=30&set mo_7=31&set mo_8=31&set mo_9=30
set mo_10=31&set mo_11=30&set mo_12=31
set /a past_y=(days/365)
set /a monthdays=days-((past_y*365)+((past_y/4)*1))&&set /a past_y=cur_y-past_y&set months=0
:setmonth
set /a minusmonth=(cur_m-1)-months
if %minusmonth% leq 0 set /a minusmonth+=12
set /a checkdays=(mo_%minusmonth%)
if %monthdays% geq %checkdays% set /a months+=1&set /a monthdays-=checkdays&goto :setmonth
set /a past_m=cur_m-months
set /a lastmonth=cur_m-1
if %lastmonth% leq 0 set /a lastmonth+=12
set /a lastmonth=mo_%lastmonth%
set /a past_d=cur_d-monthdays&set adddays=::
if %past_d% leq 0 (set /a past_m-=1&set adddays=)
if %past_m% leq 0 (set /a past_m+=12&set /a past_y-=1)
set mo_2=28&set /a leapyear=past_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
%adddays%set /a past_d+=mo_%past_m%
set d=%past_m%-%past_d%-%past_y%
for /f "tokens=*" %%a IN ('xcopy *.* /d:%d% /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)

CATATAN: Kode di atas memperhitungkan tahun kabisat, serta jumlah hari yang tepat di setiap bulan. Satu-satunya maksimum adalah jumlah hari yang telah ada sejak 0/0/0 (setelah itu menghasilkan tahun negatif).

CATATAN: Matematika hanya berjalan satu arah; itu tidak dapat dengan benar mendapatkan tanggal mendatang dari input negatif (itu akan mencoba, tetapi kemungkinan akan melewati hari terakhir bulan itu).

Dosen
sumber
3

Anda mungkin bisa melakukan ini. Anda dapat melihat pada pertanyaan ini , untuk contoh yang lebih sederhana. Kompleksitasnya datang, ketika Anda mulai membandingkan tanggal. Mungkin mudah untuk mengetahui apakah tanggalnya lebih besar atau tidak, tetapi ada banyak situasi yang perlu dipertimbangkan jika Anda harus benar-benar mendapatkan perbedaan antara dua tanggal.

Dengan kata lain - jangan mencoba untuk menciptakan ini, kecuali jika Anda benar-benar tidak dapat menggunakan alat pihak ketiga.

Paulius
sumber
3

ini tidak ada yang luar biasa, tetapi saya perlu melakukan sesuatu seperti ini hari ini dan menjalankannya sebagai tugas yang dijadwalkan dll.

file batch, DelFilesOlderThanNDays.bat di bawah ini dengan sampel exec dengan params:

DelFilesOlderThanNDays.bat 7 C: \ dir1 \ dir2 \ dir3 \ logs * .log

echo off
cls
Echo(
SET keepDD=%1
SET logPath=%2 :: example C:\dir1\dir2\dir3\logs
SET logFileExt=%3
SET check=0
IF [%3] EQU [] SET logFileExt=*.log & echo: file extention not specified (default set to "*.log")
IF [%2] EQU [] echo: file directory no specified (a required parameter), exiting! & EXIT /B 
IF [%1] EQU [] echo: number of days not specified? :)
echo(
echo: in path [ %logPath% ]
echo: finding all files like [ %logFileExt% ]
echo: older than [ %keepDD% ] days
echo(
::
::
:: LOG
echo:  >> c:\trimLogFiles\logBat\log.txt
echo: executed on %DATE% %TIME% >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt
echo: in path [ %logPath% ] >> c:\trimLogFiles\logBat\log.txt
echo: finding all files like [ %logFileExt% ] >> c:\trimLogFiles\logBat\log.txt
echo: older than [ %keepDD% ] days >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt
::
FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path" >> c:\trimLogFiles\logBat\log.txt 2<&1
IF %ERRORLEVEL% EQU 0 (
 FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path"
)
::
::
:: LOG
IF %ERRORLEVEL% EQU 0 (
 echo:  >> c:\trimLogFiles\logBat\log.txt
 echo: deleting files ... >> c:\trimLogFiles\logBat\log.txt
 echo:  >> c:\trimLogFiles\logBat\log.txt
 SET check=1
)
::
::
IF %check% EQU 1 (
 FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c del @path"
)
::
:: RETURN & LOG
::
IF %ERRORLEVEL% EQU 0 echo: deletion successfull! & echo: deletion successfull! >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt
Goran B.
sumber
3

Memperluas jawaban aku, aku melihat banyak orang bertanya tentang jalur UNC. Cukup memetakan jalur unc ke drive letter akan membuat forfile bahagia. Pemetaan dan unmapping drive dapat dilakukan secara terprogram dalam file batch, misalnya.

net use Z: /delete
net use Z: \\unc\path\to\my\folder
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"

Ini akan menghapus semua file dengan ekstensi .gz yang lebih lama dari 7 hari. Jika Anda ingin memastikan Z: tidak dipetakan ke hal lain sebelum menggunakannya, Anda bisa melakukan sesuatu yang sederhana

net use Z: \\unc\path\to\my\folder
if %errorlevel% equ 0 (
    forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
) else (
    echo "Z: is already in use, please use another drive letter!"
)
Tobias Järvelöv
sumber
3

ROBOCOPY bekerja sangat baik untuk saya. Awalnya menyarankan Iman saya. Tetapi alih-alih memindahkan file / folder ke direktori sementara lalu menghapus isi folder sementara, pindahkan file ke tempat sampah !!!

Ini adalah beberapa baris file batch cadangan saya misalnya:

SET FilesToClean1=C:\Users\pauls12\Temp
SET FilesToClean2=C:\Users\pauls12\Desktop\1616 - Champlain\Engineering\CAD\Backups

SET RecycleBin=C:\$Recycle.Bin\S-1-5-21-1480896384-1411656790-2242726676-748474

robocopy "%FilesToClean1%" "%RecycleBin%" /mov /MINLAD:15 /XA:SH /NC /NDL /NJH /NS /NP /NJS
robocopy "%FilesToClean2%" "%RecycleBin%" /mov /MINLAD:30 /XA:SH /NC /NDL /NJH /NS /NP /NJS

Ini membersihkan apa pun yang lebih tua dari 15 hari dari folder 'Temp' saya dan 30 hari untuk apa pun di folder cadangan AutoCAD saya. Saya menggunakan variabel karena garisnya bisa cukup panjang dan saya bisa menggunakannya kembali untuk lokasi lain. Anda hanya perlu menemukan path dos ke recycle bin Anda yang terkait dengan login Anda.

Ini ada di komputer kerja untuk saya dan berhasil. Saya memahami bahwa beberapa dari Anda mungkin memiliki hak yang lebih ketat tetapi tetap mencobanya;) Cari Google untuk penjelasan tentang parameter ROBOCOPY.

Bersulang!

Shawn Pauliszyn
sumber
1
Jawaban kedua yang paling banyak dipilih juga mendukung RoboCopy. Memang, Anda menggunakan opsi yang agak berbeda, tetapi dekat dengan jawaban yang ada.
Jonathan Leffler
2
Posting ini memiliki konten baru - memindahkan file ke recycle bin. Ini belum diusulkan dengan Robocopy dan sepenuhnya menjawab posting asli menggunakan perintah single-line built-in. Bekerja lebih baik daripada menggabungkan perintah 'DEL' dan 'RMDIR' karena file dapat dipulihkan dari recycle bin. Hei, aku masih baru di sini - beri aku waktu istirahat;)
Shawn Pauliszyn
2

Skrip saya untuk menghapus file yang lebih lama dari tahun tertentu:

@REM _______ GENERATE A CMD TO DELETE FILES OLDER THAN A GIVEN YEAR
@REM _______ (given in _olderthanyear variable)
@REM _______ (you must LOCALIZE the script depending on the dir cmd console output)
@REM _______ (we assume here the following line's format "11/06/2017  15:04            58 389 SpeechToText.zip")

@set _targetdir=c:\temp
@set _olderthanyear=2017

@set _outfile1="%temp%\deleteoldfiles.1.tmp.txt"
@set _outfile2="%temp%\deleteoldfiles.2.tmp.txt"

  @if not exist "%_targetdir%" (call :process_error 1 DIR_NOT_FOUND "%_targetdir%") & (goto :end)

:main
  @dir /a-d-h-s /s /b %_targetdir%\*>%_outfile1%
  @for /F "tokens=*" %%F in ('type %_outfile1%') do @call :process_file_path "%%F" %_outfile2%
  @goto :end

:end
  @rem ___ cleanup and exit
  @if exist %_outfile1% del %_outfile1%
  @if exist %_outfile2% del %_outfile2%
  @goto :eof

:process_file_path %1 %2
  @rem ___ get date info of the %1 file path
  @dir %1 | find "/" | find ":" > %2
  @for /F "tokens=*" %%L in ('type %2') do @call :process_line "%%L" %1
  @goto :eof

:process_line %1 %2
  @rem ___ generate a del command for each file older than %_olderthanyear%
  @set _var=%1
  @rem  LOCALIZE HERE (char-offset,string-length)
  @set _fileyear=%_var:~0,4%
  @set _fileyear=%_var:~7,4%
  @set _filepath=%2
  @if %_fileyear% LSS %_olderthanyear% echo @REM %_fileyear%
  @if %_fileyear% LSS %_olderthanyear% echo @del %_filepath%
  @goto :eof

:process_error %1 %2
  @echo RC=%1 MSG=%2 %3
  @goto :eof
efdummy
sumber
1

Yang ini melakukannya untuk saya. Ini berfungsi dengan tanggal dan Anda dapat mengurangi jumlah yang diinginkan dalam beberapa tahun untuk kembali ke masa:

@echo off

set m=%date:~-7,2%
set /A m
set dateYear=%date:~-4,4%
set /A dateYear -= 2
set DATE_DIR=%date:~-10,2%.%m%.%dateYear% 

forfiles /p "C:\your\path\here\" /s /m *.* /d -%DATE_DIR% /c "cmd /c del @path /F"

pause

yang /Fdi cmd /c del @path /Fpasukan file tertentu yang akan dihapus dalam beberapa kasus file dapat read-only.

itu dateYearadalah tahun Variabel dan di sana Anda dapat mengubah pengurangan sesuai dengan kebutuhan Anda sendiri

Snickbrack
sumber