แบตช์ไฟล์เพื่อลบไฟล์ที่เก่ากว่า N วัน


678

ฉันกำลังมองหาวิธีลบไฟล์ทั้งหมดที่เก่ากว่า 7 วันในไฟล์แบตช์ ฉันค้นหาในเว็บและพบตัวอย่างด้วยโค้ดหลายร้อยบรรทัดและอื่น ๆ ที่จำเป็นต้องติดตั้งยูทิลิตีบรรทัดคำสั่งพิเศษเพื่อให้งานสำเร็จ

สิ่งที่คล้ายกันสามารถทำได้ใน BASHด้วยโค้ดเพียงไม่กี่บรรทัด ดูเหมือนว่าอย่างน้อยก็สามารถสร้างไฟล์แบตช์ใน Windows ได้จากระยะไกล ฉันกำลังมองหาโซลูชันที่ทำงานในพรอมต์คำสั่งมาตรฐานของ Windows โดยไม่มีโปรแกรมอรรถประโยชน์เพิ่มเติม กรุณาอย่า PowerShell หรือ Cygwin


8
Jeff Atwood ตอบคำถามนี้ใน Serverfault ซึ่งฉันคิดว่าควรบันทึกไว้ที่นี่ serverfault.com/questions/49614/delete-files-older-than-x-days
Dusty

วิธีการใหม่ที่ใช้ไฟล์. BAT ที่ใช้คำสั่ง CMD.EXE ภายในเท่านั้นที่โพสต์ไว้ที่นี่: stackoverflow.com/questions/9746778/…
Aacini

1
gehrcke.de/timegapsได้รับการออกแบบมาเพื่อจุดประสงค์นี้ นอกจากนี้ยังช่วยให้มีรูปแบบการลบที่ซับซ้อนยิ่งขึ้น: นอกเหนือจากการเก็บไฟล์ใน 7 วันที่ผ่านมาเช่นมันยังอนุญาตให้เก็บหนึ่งไฟล์สำหรับแต่ละ 8 สัปดาห์ 12 เดือน 2 ปีที่ผ่านมา
ดร. Jan-Philip Gehrcke

คำตอบ:


1071

สนุก:

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

ดูforfilesเอกสารประกอบสำหรับรายละเอียดเพิ่มเติม

สำหรับสารพัดเพิ่มเติมโปรดดูที่AZ ดัชนีของบรรทัดคำสั่ง

ถ้าคุณไม่ได้forfilesติดตั้งบนเครื่องของคุณคัดลอกจากWindows Server 2003ไปยังเครื่องของคุณ Windows XP %WinDir%\system32\ที่ สิ่งนี้เป็นไปได้เนื่องจาก EXE เข้ากันได้อย่างสมบูรณ์ระหว่าง Windows Server 2003 และ Windows XP

Windows และ Windows Server เวอร์ชันที่ใหม่กว่าติดตั้งเป็นค่าเริ่มต้น

สำหรับ Windows 7 และใหม่กว่า (รวมถึง Windows 10):

ไวยากรณ์มีการเปลี่ยนแปลงเล็กน้อย ดังนั้นคำสั่งที่อัพเดตคือ:

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

12
ควรจะเป็นเด @FILE กรณีที่สำคัญนอกจากนี้ผมขอแนะนำให้ใช้ c / ก้อง @FILE สำหรับการทดสอบ
รัสเซลสตีน

40
@Russell: @PATH เป็นเส้นทางแบบเต็มรวมถึงชื่อ @FILE เป็นชื่อเท่านั้นดังนั้นหากคุณจัดการกับโฟลเดอร์ย่อยมันจะไม่ทำงาน
gregmac

86
โปรดทราบว่าหากคุณต้องการไฟล์ OLDER มากกว่า 10 วันคุณจะต้องระบุ -d "-10" -ve หมายถึง "เก่ากว่า", + ve หมายถึง "ใหม่กว่า" คุณยังสามารถระบุรูปแบบ DDMMYY หรือ -DDMMYY เป็นพารามิเตอร์ถึง -d
gregmac

42
ฉันใช้ไวยากรณ์นี้ใน Win Server 2008: forfiles / P "C: \ Mysql_backup" / S / M * .sql / D -30 / C "cmd / c del @PATH"
jman

9
คำตอบนี้ใช้ได้เมื่อ "เก่ากว่า 7 วัน" ถูกกำหนดเป็น "แก้ไขมากกว่า 7 วันที่ผ่านมา" แทนที่จะ "สร้างมากกว่า 7 วันที่ผ่านมา" วิธีหลังสามารถทำได้?
TimS

76

รันคำสั่งต่อไปนี้:

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

ย้ายไฟล์ทั้งหมด (โดยใช้ / mov ซึ่งย้ายไฟล์แล้วลบออกเมื่อเทียบกับ / ย้ายซึ่งย้ายทั้งไฟล์ทั้งหมดที่ถูกลบไปแล้ว) ผ่าน robocopy ไปยังตำแหน่งอื่นจากนั้นเรียกใช้คำสั่งลบบนเส้นทางนั้นและคุณทั้งหมด ดี.

นอกจากนี้หากคุณมีไดเรกทอรีที่มีข้อมูลจำนวนมากคุณสามารถใช้/mirสวิตช์ได้


5
ส่วนใหญ่นี่เป็นคำตอบที่ไม่สามารถทำได้ ถ้าฉันมีไดเรกทอรีที่มีข้อมูลจำนวนมากมันจะไม่ทำงานได้ดี ฉันไปกับหนึ่งในคำตอบที่ไม่ได้ "ในสถานที่"
adamb0mb

5
@ adamb0mb ไม่สามารถใช้การได้ - หาก"ปลายทาง"อยู่ในระบบไฟล์เดียวกับ"แหล่งที่มา"การดำเนินการย้ายค่อนข้างเบา robocopy มีความแข็งแกร่งจริง ๆแล้วมันจะใช้งานได้จริงสำหรับขนาดไดเรกทอรีใด ๆ ชื่อไฟล์ที่คลุมเครือโดยทั่วไปมีความยาวเส้นทางโดยพลการและรวมไดเรกทอรีถ้าคุณต้องการ ฉันจะใช้rd /s /q c:\destinationแทนdelคำสั่งแม้ว่าหรือใช้การrobocopy /mir c:\emptydir c:\destinationทำงานอื่นเพื่อล้างไดเรกทอรีหากคุณคาดว่าจะมีปัญหากับชื่อไฟล์
syneticon-dj

12
นอกจากนี้ robocopy รองรับเส้นทาง UNC ซึ่งforfilesคำตอบที่ยอมรับจะไม่ทำ
syneticon-dj

3
ความคิดของฉันมีมากขึ้นตามสาย: "ไฟล์ของฉันมีอยู่แล้วในที่ที่ฉันต้องการพวกเขาฉันไม่ต้องการที่จะย้ายพวกเขา" "การลบไฟล์เป็นสิ่งที่คุณทำอย่างมีเหตุผลทำอย่างนั้นอย่าให้ Robocopy ทำมากเกินไป"
adamb0mb

3
ฉันแนะนำหนึ่งซับนี้สำหรับการดูไฟล์ทั้งหมดในC:\testเก่ากว่า 7 วัน ในการลบไฟล์ที่เปลี่ยนechoไปdel:forfiles /p "C:\test" /m "*.*" /c "cmd /c echo @file" /D -7
poweruser

25

ตกลงเบื่อเล็กน้อยและเกิดขึ้นกับสิ่งนี้ซึ่งมีการแทนที่ยุคลินุกซ์ของคนยากจนในรุ่น จำกัด สำหรับการใช้งานรายวัน (ไม่มีการเก็บรักษาเวลา):

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

การใช้งาน

set /a strip=day*7: เปลี่ยน7สำหรับจำนวนวันที่จะเก็บ

set dSource=C:\temp : นี่เป็นไดเรกทอรีเริ่มต้นเพื่อตรวจสอบไฟล์

หมายเหตุ

นี่คือรหัสที่ไม่ทำลายมันจะแสดงสิ่งที่จะเกิดขึ้น

เปลี่ยน:

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

เพื่อสิ่งที่ชอบ:

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

ดังนั้นไฟล์จึงถูกลบจริงๆ

กุมภาพันธ์ : กำหนดค่าตายตัวถึง 28 วัน ปี Bissextile เป็นนรกที่จะเพิ่มจริง ๆ หากมีคนมีความคิดที่จะไม่เพิ่มรหัส 10 บรรทัดให้ไปข้างหน้าและโพสต์ดังนั้นฉันเพิ่มลงในรหัสของฉัน

ตอนที่ : ฉันไม่ได้คำนึงถึงเวลาเนื่องจากความต้องการคือการลบไฟล์ที่เก่ากว่าวันที่กำหนดการใช้เวลา / นาทีจะลบไฟล์จากวันที่มีไว้เพื่อการรักษา

ข้อ จำกัด

ยุคใช้รูปแบบวันที่สั้น ๆ ของคุณคือ YYYY-MM-DD มันจะต้องมีการปรับสำหรับการตั้งค่าอื่น ๆ หรือการประเมินผลรันไทม์ (อ่าน sShortTime, การกำหนดค่าผูกพันผู้ใช้กำหนดค่าลำดับฟิลด์ที่เหมาะสมในตัวกรองและใช้ตัวกรองเพื่อดึงข้อมูลที่ถูกต้องจากการโต้แย้ง)

ฉันไม่ได้พูดถึงว่าฉันเกลียดการจัดรูปแบบอัตโนมัติของบรรณาธิการหรือไม่ มันลบบรรทัดว่างและ copy-paste เป็นนรก

ฉันหวังว่านี่จะช่วยได้.


4
+1 สำหรับโค้ดที่ไม่ทำลายฉันจะพยายามจำไว้เมื่อฉันแสดงตัวอย่างโค้ดด้วยตัวเอง
Haugholt

5
ช้าและไม่เกี่ยวข้องกันโดยสิ้นเชิง แต่7daysclean.cmdฟังดูเหมือนเป็นชื่อที่ยอดเยี่ยมสำหรับวงดนตรี Synth-Punk
Flonk

21
forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"

คุณควรทำ/d -3(3 วันก่อนหน้า) มันใช้ได้ดีสำหรับฉัน ดังนั้นกระบวนการที่ซับซ้อนทั้งหมดอาจอยู่ในถังขยะ ยังforfilesไม่รองรับเส้นทาง UNC ดังนั้นทำการเชื่อมต่อเครือข่ายกับไดรฟ์เฉพาะ


3
ข้อผิดพลาดเหมือนกับคำตอบอื่น ๆ (รวมถึงคำตอบที่ยอมรับ) นิสัยแปลก ๆ ในการระบุนี้*.*มาจากไหน สัญลักษณ์แทน*.*ไม่ตรงกับไฟล์ทั้งหมดใน Windows จะจับคู่ไฟล์กับ.ในชื่อเท่านั้น OP ไม่เคยพูดอะไรเกี่ยวกับการกำหนด.ชื่อไฟล์ พารามิเตอร์ที่เหมาะสมคือ/M *แต่นี่เป็นค่าเริ่มต้นอยู่แล้ว ไม่จำเป็นต้องมี/Mเลย
AnT

@AnT: คุณแน่ใจเหรอ? ฉันคิดว่ามัน*.*ทำงานเหมือนกับ*ใน Windows อันที่จริงฉันเพิ่งลองใช้มันบนคอมพิวเตอร์ของฉันและdir *.*ระบุไว้test fileว่าเป็นไฟล์ที่ไม่มีนามสกุล
Andreas Rejbrand

1
@Andreas Rejbrand: ฉันคิดว่ามันน่าแปลกใจเช่นกัน แต่การรักษา*.*จะไม่สอดคล้องกันระหว่างการพูด, dirและตัวเลือกในการ-m forfilesมาส-m *.*ก์จะข้ามชื่อไฟล์ที่ไม่มีนามสกุลอย่างที่ฉันได้กล่าวไว้ในความคิดเห็นของฉันด้านบน (ลองด้วยตัวเอง) ส่วนที่ตลกนี่คือเอกสาร MS ระบุอย่างชัดเจนว่า-m *.*เป็นค่าเริ่มต้น อย่างไรก็ตามหากคุณลองใช้งานในชีวิตจริงคุณจะเห็นว่าค่าเริ่มต้นนั้นแท้จริงแล้ว-m *- ไฟล์ทั้งหมดจะถูกทำซ้ำ
ANT

1
หน้าเอกสารของ MS นี้ - technet.microsoft.com/en-us/library/cc753551(v=ws.11).aspx - มีข้อผิดพลาดจำนวนมาก (เช่นในตัวอย่าง) เนื่องจากผู้เขียนเอกสารเชื่อว่า*.*รูปแบบที่ใช้นั้นไม่ถูกต้องไปยังไฟล์ทั้งหมด คำถามเกี่ยวกับ "นิสัยแปลก ๆ นี้" ที่เกี่ยวกับการซ้ำซากของฉันนั้นไม่มีเหตุผลใด ๆ สำหรับการรักษา*.*และการปฏิบัติ*ที่เทียบเท่ากับการประชุม Windows ที่ยาวนาน อย่างไรก็ตาม/mตัวเลือกในforfilesการละเมิดข้อตกลงนั้นด้วยเหตุผลบางอย่าง
AnT

1
ความเป็นมาของwildcard 5 รายการใน Windows: blogs.msdn.microsoft.com/jeremykuhne/2017/06/04/…
MSalters

18

มีลักษณะที่ฉันคำตอบให้กับคำถามที่คล้ายกัน :

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"

ไฟล์นี้จะลบที่เก่ากว่าวันที่กำหนด ฉันแน่ใจว่าสามารถแก้ไขได้เพื่อย้อนกลับเจ็ดวันนับจากวันที่ปัจจุบัน

ปรับปรุง:ฉันสังเกตเห็นว่า HerbCSO ได้รับการปรับปรุงในสคริปต์ข้างต้น ฉันแนะนำให้ใช้เวอร์ชั่นของเขาแทน


12

คำสั่งของฉันคือ

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

@PATH - เป็นเพียงเส้นทางในกรณีของฉันดังนั้นฉันต้องใช้ @PATH\@FILE

ยังforfiles /?ไม่ทำงานสำหรับฉันด้วย แต่forfiles(โดยไม่มี "?") ก็ใช้ได้ดี

และคำถามเดียวที่ฉันมี: วิธีเพิ่มหลายหน้ากาก (เช่น " .log | .bak") ได้อย่างไร

ทั้งหมดนี้เกี่ยวกับ forfiles.exe ที่ฉันดาวน์โหลดที่นี่ (ใน win XP)

แต่ถ้าคุณใช้เซิร์ฟเวอร์ Windows forfiles.exe ควรมีอยู่แล้วและแตกต่างจากรุ่น ftp นั่นคือเหตุผลที่ฉันควรแก้ไขคำสั่ง

สำหรับ Windows Server 2003 ฉันใช้คำสั่งนี้:

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

9

มีคำถามที่เกี่ยวข้องกับวันที่ / เวลาที่สัมพันธ์กันบ่อยมากที่จะแก้ด้วยไฟล์แบทช์ แต่ล่ามบรรทัดคำสั่งcmd.exeไม่มีฟังก์ชั่นสำหรับการคำนวณวันที่ / เวลา โซลูชันการทำงานที่ดีจำนวนมากที่ใช้แอปพลิเคชันคอนโซลหรือสคริปต์เพิ่มเติมได้รับการโพสต์แล้วที่นี่ในหน้าอื่น ๆ ของ Stack Overflow และบนเว็บไซต์อื่น ๆ

ทั่วไปสำหรับการดำเนินการตามวันที่ / เวลาคือข้อกำหนดในการแปลงสตริงวันที่ / เวลาเป็นวินาทีตั้งแต่วันที่กำหนด UTC คือ 1970-01-01 00:00:00 UTC แต่สามารถใช้วันต่อมาได้ขึ้นอยู่กับช่วงวันที่ที่ต้องการสนับสนุนงานเฉพาะ

เจโพสต์7daysclean.cmdที่มีได้อย่างรวดเร็ว "วันที่วินาที" วิธีการแก้ปัญหาสำหรับบรรทัดคำสั่งล่ามcmd.exe แต่มันก็ไม่ได้ใช้เวลาปีกระโดดที่ถูกต้องเข้าบัญชี JRโพสต์Add-onสำหรับพิจารณาวันอธิกสุรทินในปีปัจจุบัน แต่ไม่สนใจปีอธิกสุรทินอื่น ๆ ตั้งแต่ปีฐานคือตั้งแต่ปี 1970

ฉันใช้ตารางแบบคงที่ (อาร์เรย์) 20 ปีที่สร้างขึ้นครั้งเดียวด้วยฟังก์ชั่น C ขนาดเล็กเพื่อรับจำนวนวันอย่างรวดเร็วรวมถึงวันอธิกสุรทินจาก 1970-01-01 ในฟังก์ชันแปลงวันที่ / เวลาในแอปพลิเคชันของฉันที่เขียนด้วย C / C ++

วิธีตารางนี้เร็วมากสามารถใช้ในชุดรหัสโดยใช้คำสั่งสำหรับ ดังนั้นฉันจึงตัดสินใจรหัสรูทีนย่อย batch GetSecondsซึ่งคำนวณจำนวนวินาทีตั้งแต่ 1970-01-01 00:00:00 UTC สำหรับสตริงวันที่ / เวลาที่ส่งผ่านไปยังรูทีนนี้

หมายเหตุ:วินาที Leap จะไม่นำมาพิจารณาเนื่องจากระบบไฟล์ Windows ไม่สนับสนุนวินาทีกระโดด

ก่อนตาราง:

  1. วันตั้งแต่ 1970-01-01 00:00:00 UTC สำหรับแต่ละปีรวมถึงวันก้าวกระโดด

    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
    

    การคำนวณวินาทีสำหรับปี 2039 ถึง 2106 ด้วยยุคเริ่มต้น 1970-01-01 เป็นไปได้เฉพาะกับการใช้ตัวแปร 32 บิตที่ไม่ได้ลงชื่อคือความยาวที่ไม่ได้ลงนาม (หรือ int ที่ไม่ได้ลงชื่อ) ใน C / C ++

    แต่cmd.exeใช้สำหรับนิพจน์ทางคณิตศาสตร์ซึ่งเป็นตัวแปร 32 บิตที่เซ็นชื่อ ดังนั้นค่าสูงสุดคือ 2147483647 (0x7FFFFFFF) ซึ่งคือ 2038-01-19 03:14:07

  2. ข้อมูล Leap ปี (ไม่ / ใช่) สำหรับปี 1970 ถึง 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. จำนวนวันถึงวันแรกของแต่ละเดือนในปีปัจจุบัน

                       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
    

การแปลงวันที่เป็นวินาทีตั้งแต่ 1970-01-01 ค่อนข้างง่ายโดยใช้ตารางเหล่านั้น

โปรดให้ความสนใจ!

รูปแบบของสตริงวันที่และเวลาขึ้นอยู่กับการตั้งค่าภูมิภาคและภาษาของ Windows คั่นและการสั่งซื้อของสัญญาณได้รับมอบหมายให้ตัวแปรสภาพแวดล้อมDay, MonthและYearในครั้งแรกสำหรับวงGetSecondsจะต้องมีการปรับให้เข้ากับวันท้องถิ่นรูปแบบที่ / เวลาในกรณีที่จำเป็น

มันเป็นสิ่งจำเป็นที่จะปรับตัวสตริงวันที่ของตัวแปรสภาพแวดล้อมถ้ารูปแบบวันที่ในตัวแปรสภาพแวดล้อมวันจะแตกต่างกับรูปแบบวันที่ใช้โดยคำสั่งFOR%%~tFบน

ตัวอย่างเช่นเมื่อ%DATE%ขยายเป็นSun 02/08/2015ในขณะที่%%~tFขยาย02/08/2015 07:38 PMโค้ดด้านล่างสามารถใช้กับการแก้ไขบรรทัดที่ 4 เป็น:

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

ส่งผลให้เกิดการส่งผ่านรูทีนย่อยเพียง02/08/2015- สตริงวันที่โดยไม่มีตัวอักษร 3 ตัวของตัวย่อวันทำงานและตัวคั่นช่องว่าง

อีกวิธีหนึ่งต่อไปนี้สามารถใช้เพื่อผ่านวันที่ปัจจุบันในรูปแบบที่ถูกต้อง:

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

ตอนนี้ผ่านมา 10 ตัวอักษรจากสตริงวันที่จะถูกส่งผ่านไปยังฟังก์ชั่นGetSecondsและดังนั้นจึงไม่สำคัญว่าถ้าสตริงวันของตัวแปรสภาพแวดล้อมของวันคือมีหรือไม่มีวันเป็นเวลานานเป็นวันและเดือนที่อยู่เสมอด้วยตัวเลข 2 หลักในการสั่งซื้อที่คาดหวังคือในรูปแบบหรือdd/mm/yyyy dd.mm.yyyy

นี่คือรหัสแบตช์พร้อมคำอธิบายความคิดเห็นซึ่งเพิ่งแสดงว่าไฟล์ใดที่จะลบและไฟล์ใดที่จะเก็บไว้ในC:\Tempโครงสร้างโฟลเดอร์ดูรหัสสำหรับวงแรก

@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

เพื่อประสิทธิภาพสูงสุดจะเป็นการดีที่สุดที่จะลบความคิดเห็นทั้งหมดเช่นทุกบรรทัดที่ขึ้นต้นด้วยremหลังจากช่องว่างนำหน้า 0-4

และอาร์เรย์สามารถมีขนาดเล็กลงเช่นลดช่วงเวลาจาก 1980-01-01 00:00:00 ถึง 2038-01-19 03:14:07 ตามที่ได้รับการสนับสนุนในขณะนี้โดยรหัสชุดงานด้านบนเช่น 2015-01 -01 ถึง 2019-12-31 ตามรหัสด้านล่างใช้ซึ่งลบไฟล์ที่เก่ากว่า 7 วันในC:\Tempโครงสร้างโฟลเดอร์

นอกจากนี้รหัสชุดด้านล่างได้รับการปรับให้เหมาะสมกับรูปแบบเวลา 24 ชั่วโมง

@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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบวันที่และเวลาและการเปรียบเทียบเวลาไฟล์บน Windows ดูคำตอบของฉันในค้นหาว่าไฟล์เก่ากว่า 4 ชั่วโมงในไฟล์แบตช์พร้อมข้อมูลเพิ่มเติมมากมายเกี่ยวกับเวลาของไฟล์


9

DelOldFiles.vbsคัดลอกโค้ดนี้และบันทึกเป็น

การใช้งานใน CMD: cscript //nologo DelOldFiles.vbs 15

15 หมายถึงการลบไฟล์ที่เก่ากว่า 15 วันในอดีต

  '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

8

สำหรับ Windows Server 2008 R2:

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

จะเป็นการลบไฟล์. sqlทั้งหมดที่เก่ากว่า90วัน


7

ใช้ไฟล์

มีหลายรุ่น ก่อนหน้านี้ใช้พารามิเตอร์สไตล์ unix

รุ่นของฉัน (สำหรับเซิร์ฟเวอร์ 2000 - ไม่ต้องเว้นวรรคหลังจากสวิตช์) -

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

หากต้องการเพิ่มไฟล์ใน XP ให้รับ exe จากftp://ftp.microsoft.com/ResKit/y2kfix/x86/

และเพิ่มลงใน C: \ WINDOWS \ system32


11
@Kibbee มันไม่ได้เป็นคำตอบเดียวกันกับไวยากรณ์ที่แตกต่างกัน นี่คือความพยายามอัจฉริยะที่จะช่วย เป็นที่รู้จักน้อยมากในบรรทัดคำสั่งของ windows ฉันใช้เวลาหลายชั่วโมงในการทำให้เครื่องขัดข้อง บิตข้อมูลที่สำคัญสำหรับฉันคือข้อเท็จจริงที่ว่ามีเวอร์ชันที่แตกต่างกัน (ที่มีไวยากรณ์แตกต่างกัน) และฉันจำเป็นต้องลบช่องว่างออก ไม่มีสิ่งเหล่านี้รวมอยู่ในคำตอบเดิม (ฉันจะได้แสดงความคิดเห็นกับคำตอบ แต่ฉันไม่มีสิทธิ์
Aidan Ewen

ข้อผิดพลาดเหมือนกับคำตอบอื่น ๆ (รวมถึงคำตอบที่ยอมรับ) สัญลักษณ์แทน*.*ในforfilesไม่ตรงกับไฟล์ทั้งหมด มันจะจับคู่ไฟล์ที่มี.ในชื่อเท่านั้น (เช่นไฟล์ที่มีนามสกุล) OP ไม่เคยพูดอะไรเกี่ยวกับการกำหนด.ชื่อไฟล์ พารามิเตอร์ที่เหมาะสมคือ/M *แต่นี่เป็นค่าเริ่มต้นอยู่แล้ว ไม่จำเป็นต้องมี/Mเลย
An

7

สำหรับ windows 2012 R2 สิ่งต่อไปนี้จะได้ผล:

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

เพื่อดูไฟล์ที่จะถูกลบใช้สิ่งนี้

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

สิ่งนี้สามารถใช้งานได้ใน Windows Server 2008 ขึ้นไปและ Windows 7
kwrl

6

IMO, JavaScript จะค่อยๆกลายเป็นมาตรฐานการเขียนสคริปต์สากล: มันอาจมีอยู่ในผลิตภัณฑ์มากกว่าภาษาสคริปต์อื่น ๆ (ใน Windows มันสามารถใช้ได้โดยใช้ Windows Scripting Host) ฉันต้องล้างไฟล์เก่าในโฟลเดอร์จำนวนมากดังนั้นนี่คือฟังก์ชั่น JavaScript สำหรับทำสิ่งนี้:

// 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);
    }
}

เพื่อให้แต่ละโฟลเดอร์ล้างเพียงเพิ่มการโทรอื่นไปยังฟังก์ชัน clearFolder () รหัสเฉพาะนี้ยังเก็บไฟล์ exe และ dll และล้างโฟลเดอร์ย่อยด้วย


6

วิธีการเกี่ยวกับการปรับเปลี่ยนนี้ใน7daysclean.cmdจะพิจารณาปีอธิกสุรทิน?

มันสามารถทำได้ในการเข้ารหัสน้อยกว่า 10 บรรทัด!

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

แก้ไขโดย Mofi:

เงื่อนไขข้างต้นสนับสนุนโดยJRประเมินว่าเป็นเท็จเสมอเนื่องจากไวยากรณ์ไม่ถูกต้อง

และMonth GEQ 2ยังเป็นความผิดเพราะการเพิ่ม 86400 วินาทีสำหรับอีกหนึ่งวันจะต้องทำในปีอธิกสุรทินสำหรับเดือนมีนาคมถึงธันวาคม แต่ไม่ใช่สำหรับเดือนกุมภาพันธ์

รหัสที่ใช้งานได้เพื่อพิจารณาวันก้าวกระโดด - ในปีปัจจุบันเท่านั้น - ในแบตช์ไฟล์7daysclean.cmdโพสต์โดยJayจะเป็น:

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

5

ฉันอาจเพิ่มส่วนร่วมที่ต่ำต้อยให้กับกระทู้ที่มีค่านี้ ฉันพบว่าโซลูชันอื่นอาจกำจัดข้อความแสดงข้อผิดพลาดจริง แต่ไม่สนใจ% ERRORLEVEL% ซึ่งเป็นสัญญาณว่าแอปพลิเคชันของฉันล้มเหลว และฉันต้องการ% 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||echo found success

ใช้ oneliner เพื่อส่งคืน 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

ใช้ oneliner เพื่อให้ ERRORLEVEL เป็นศูนย์สำหรับความสำเร็จในบริบทของ batchfile ท่ามกลางรหัสอื่น ๆ (ver> nul รีเซ็ต 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

สำหรับขั้นตอนงานของ บริษัท ตัวแทนของเซิร์ฟเวอร์ SQL CmdExec ฉันมีที่ดินต่อไปนี้ ฉันไม่ทราบว่าเป็นข้อบกพร่องหรือไม่ แต่ CmdExec ภายในขั้นตอนนี้จะรับรู้บรรทัดแรกของรหัสเท่านั้น:

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%

5

เอ้ยคำตอบมากมายแล้ว เส้นทางที่ง่ายและสะดวกที่ฉันพบคือเรียกใช้ ROBOCOPY.EXE สองครั้งตามลำดับจากคำสั่งบรรทัดคำสั่ง Windows เดียวโดยใช้พารามิเตอร์&

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

ในตัวอย่างนี้ทำงานโดยเลือกไฟล์ทั้งหมด ( . ) ที่เก่ากว่า 30 วันและย้ายไปยังโฟลเดอร์เป้าหมาย คำสั่งที่สองทำเช่นเดียวกันอีกครั้งด้วยการเพิ่มคำสั่งPURGEซึ่งหมายถึงลบไฟล์ในโฟลเดอร์เป้าหมายที่ไม่มีอยู่ในโฟลเดอร์ต้นทาง โดยพื้นฐานแล้วคำสั่งแรกจะย้ายไฟล์และลบครั้งที่สองเนื่องจากไม่มีอยู่ในโฟลเดอร์ซอร์สเมื่อคำสั่งที่สองถูกเรียกใช้

ศึกษาเอกสารของ ROBOCOPY และใช้สวิตช์ / L เมื่อทำการทดสอบ


4

หากคุณมีชุดทรัพยากร XP คุณสามารถใช้ robocopy เพื่อย้ายไดเรกทอรีเก่าทั้งหมดไปยังไดเรกทอรีเดียวจากนั้นใช้ rmdir เพื่อลบเพียงรายการเดียว:

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

4

ฉันคิดว่าคำตอบของ e.Jamesนั้นดีเพราะใช้งานได้กับ Windows รุ่นที่ไม่ได้แก้ไขก่อนที่จะเป็น Windows 2000 SP4 (และอาจเร็วกว่านี้) แต่จำเป็นต้องเขียนลงในไฟล์ภายนอก นี่คือเวอร์ชันดัดแปลงที่ไม่ได้สร้างไฟล์ข้อความภายนอกในขณะที่รักษาความเข้ากันได้:

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)

จะเป็นจริงกับคำถามเดิมที่นี่มันอยู่ในสคริปต์ที่ทำคณิตศาสตร์ทั้งหมดสำหรับคุณถ้าคุณเรียกมันด้วยจำนวนวันเป็นพารามิเตอร์:

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)

หมายเหตุ: รหัสด้านบนนี้ใช้เวลาในการพิจารณาปีอธิกสุรทินรวมถึงจำนวนวันที่แน่นอนในแต่ละเดือน สูงสุดเพียงอย่างเดียวคือจำนวนวันทั้งหมดที่ได้รับตั้งแต่ 0/0/06 (หลังจากนั้นจะส่งกลับปีเชิงลบ)

หมายเหตุ: คณิตศาสตร์มีเพียงทางเดียวเท่านั้น ไม่สามารถรับวันที่ในอนาคตจากการป้อนเชิงลบได้อย่างถูกต้อง (จะลอง แต่จะผ่านไปได้ในวันสุดท้ายของเดือน)


3

คุณสามารถดึงสิ่งนี้ออกได้ คุณสามารถดูคำถามนี้เพื่อเป็นตัวอย่างที่ง่ายกว่า ความซับซ้อนเกิดขึ้นเมื่อคุณเริ่มเปรียบเทียบวันที่ อาจเป็นการง่ายที่จะบอกว่าวันที่นั้นใหญ่กว่าหรือไม่ แต่มีหลายสถานการณ์ที่ต้องพิจารณาหากคุณต้องการรับความแตกต่างระหว่างสองวัน

กล่าวอีกนัยหนึ่ง - อย่าพยายามประดิษฐ์สิ่งนี้เว้นแต่คุณจะไม่สามารถใช้เครื่องมือของบุคคลที่สามได้


3

มันไม่มีอะไรน่าอัศจรรย์ แต่ฉันต้องทำอะไรแบบนี้วันนี้และทำงานตามที่กำหนดไว้ ฯลฯ

ไฟล์แบตช์ DelFilesOlderThanNDays.bat ด้านล่างพร้อมตัวอย่าง exec w / 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

3

จากคำตอบของ aku ฉันเห็นผู้คนมากมายถามเกี่ยวกับเส้นทาง UNC เพียงทำแผนที่เส้นทางที่ไม่ได้ใช้กับอักษรระบุไดรฟ์จะทำให้ไฟล์มีความสุข การแม็พและการแม็พไดรฟ์สามารถทำได้โดยทางโปรแกรมในไฟล์แบตช์ตัวอย่างเช่น

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"

การดำเนินการนี้จะลบไฟล์ทั้งหมดที่มีนามสกุล. gz ซึ่งเก่ากว่า 7 วัน หากคุณต้องการให้แน่ใจว่า Z: ไม่ได้แมปกับสิ่งอื่นก่อนใช้งานคุณสามารถทำสิ่งที่ง่าย ๆ เช่น

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!"
)

3

ROBOCOPY ใช้งานได้ดีสำหรับฉัน เริ่มแรกแนะนำ Iman ของฉัน แต่แทนที่จะย้ายไฟล์ / โฟลเดอร์ไปยังไดเรกทอรีชั่วคราวแล้วลบเนื้อหาของโฟลเดอร์ชั่วคราวย้ายไฟล์ไปที่ถังขยะ !!!

นี่เป็นไฟล์แบตช์สำรองของฉันไม่กี่บรรทัดเช่น:

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

มันจะล้างสิ่งที่เก่ากว่า 15 วันจากโฟลเดอร์ 'Temp' ของฉันและ 30 วันสำหรับทุกอย่างในโฟลเดอร์สำรอง AutoCAD ของฉัน ฉันใช้ตัวแปรเพราะเส้นอาจยาวมากและฉันสามารถนำกลับมาใช้ใหม่ในที่อื่นได้ คุณเพียงแค่ต้องค้นหาเส้นทาง dos ไปยังถังรีไซเคิลของคุณที่เกี่ยวข้องกับการเข้าสู่ระบบของคุณ

นี่คือคอมพิวเตอร์ที่ทำงานสำหรับฉันและใช้งานได้ ฉันเข้าใจว่าคุณบางคนอาจมีสิทธิ์ที่ จำกัด มากขึ้น แต่ลองดูสิ;) ค้นหาคำอธิบายเกี่ยวกับพารามิเตอร์ ROBOCOPY ของ Google

ไชโย!


1
คำตอบที่มีอันดับรองลงมาอันดับสองยังมีผลบังคับใช้กับ RoboCopy จริงอยู่ที่คุณใช้ตัวเลือกที่แตกต่างกันบ้าง แต่ใกล้กับคำตอบที่มีอยู่
Jonathan Leffler

2
โพสต์นี้มีเนื้อหาใหม่ - ย้ายไฟล์ไปยังถังรีไซเคิล สิ่งนี้ยังไม่ได้รับการเสนอกับ Robocopy และจะตอบกระทู้ทั้งหมดโดยใช้คำสั่งแบบบรรทัดเดียวในตัว ทำงานได้ดีกว่าการรวมคำสั่ง 'DEL' และ 'RMDIR' เนื่องจากไฟล์สามารถเรียกคืนได้จากถังรีไซเคิล เฮ้ฉันยังใหม่อยู่ที่นี่ - ให้ฉันหยุดพัก)
Shawn Pauliszyn

2

สคริปต์ของฉันเพื่อลบไฟล์ที่เก่ากว่าปีที่ระบุ:

@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

1

อันนี้ทำเพื่อฉัน มันทำงานร่วมกับวันที่และคุณสามารถแทนที่จำนวนที่ต้องการในปีที่จะย้อนเวลากลับไป:

@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

/Fในcmd /c del @path /Fกองกำลังของแฟ้มที่เฉพาะเจาะจงที่จะลบในบางกรณีไฟล์สามารถอ่านอย่างเดียว

dateYearเป็นตัวแปรปีและมีคุณสามารถเปลี่ยนลบคุณกับความต้องการของคุณเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.