大家好,現在有個需求,需要通過腳本自動洗掉指定目錄下“創建日期”超過60天的檔案。
剛才在網上查到用forfiles命令可以實作洗掉“修改日期”超過60天的,不知道如何指定“創建日期”
腳本如下:請指教
set SrcDir=C:\Test
set DaysAgo=60
forfiles /p %SrcDir% /s /m *.* /d -%DaysAgo% /c "cmd /c del /f /q /a @path"
uj5u.com熱心網友回復:
set SrcDir=C:\Testset DaysAgo=60
forfiles /p %SrcDir% /s /m *.* /d /tc -%DaysAgo% /c "cmd /c del /f /q /a @path"
不一定對,僅供參考。
C:\>dir /?
顯示目錄中的檔案和子目錄串列。
DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]sortorder]] [/P] [/Q] [/S] [/T[[:]timefield]] [/W] [/X] [/4]
[drive:][path][filename]
指定要列出的驅動器、目錄和/或檔案。
/A 顯示具有指定屬性的檔案。
attributes D 目錄 R 只讀檔案
H 隱藏檔案 A 準備存檔的檔案
S 系統檔案 - 表示“否”的前綴
/B 使用空格式(沒有標題資訊或摘要)。
/C 在檔案大小中顯示千位數分隔符。這是默認值。用 /-C 來
禁用分隔符顯示。
/D 跟寬式相同,但檔案是按欄分類列出的。
/L 用小寫。
/N 新的長串列格式,其中檔案名在最右邊。
/O 用分類順序列出檔案。
sortorder N 按名稱(字母順序) S 按大小(從小到大)
E 按擴展名(字母順序) D 按日期/時間(從先到后)
G 組目錄優先 - 反轉順序的前綴
/P 在每個資訊螢屏后暫停。
/Q 顯示檔案所有者。
/S 顯示指定目錄和所有子目錄中的檔案。
/T 控制顯示或用來分類的時間字符域。
timefield C 創建時間
A 上次訪問時間
W 上次寫入的時間
/W 用寬串列格式。
/X 顯示為非 8.3 檔案名產生的短名稱。格式是 /N 的格式,
短名稱插在長名稱前面。如果沒有短名稱,在其位置則
顯示空白。
/4 用四位數字顯示年
可以在 DIRCMD 環境變數中預先設定開關。通過添加前綴 - (破折號)
來替代預先設定的開關。例如,/-W。
uj5u.com熱心網友回復:
C:\>forfiles /?FORFILES [/P pathname] [/M searchmask] [/S]
[/C command] [/D [+ | -] {yyyy-MM-dd | dd}]
描述:
選擇一個檔案(或一組檔案)并在那個檔案上
執行一個命令。這有助于批處理作業。
引數串列:
/P pathname 表示開始搜索的路徑。默認檔案夾是當前作業的
目錄 (.)。
/M searchmask 根據搜索掩碼搜索檔案。默認搜索掩碼是 '*'。
/S 指導 forfiles 遞回到子目錄。像 "DIR /S"。
/C command 表示為每個檔案執行的命令。命令字串應該
用雙引號括起來。
默認命令是 "cmd /c echo @file"。下列變數
可以用在命令字串中:
@file - 回傳檔案名。
@fname - 回傳不帶擴展名的檔案名。
@ext - 只回傳檔案的擴展。
@path - 回傳檔案的完整路徑。
@relpath - 回傳檔案的相對路徑。
@isdir - 如果檔案型別是目錄,回傳 "TRUE";
如果是檔案,回傳 "FALSE"。
@fsize - 以位元組為單位回傳檔案大小。
@fdate - 回傳檔案上一次修改的日期。
@ftime - 回傳檔案上一次修改的時間。
要在命令列包括特殊字符,字符請以 0xHH
形式使用十六進制代碼(例如,0x09 為 tab)。
內部 CMD.exe 命令前面應以 "cmd /c" 開始。
/D date 選擇檔案,其上一次修改日期大于或等于 (+),
或者小于或等于 (-) 用 "yyyy-MM-dd" 格式指定的日期;
或選擇檔案,其上一次修改日期大于或等于 (+)
當前日期加 "dd" 天,或者小于或等于 (-) 當前
日期減 "dd" 天。有效的 "dd" 天數可以是
0 - 32768 范圍內的任何數字。如果沒有指定,
"+" 被當作默認符號。
/? 顯示幫助訊息。
例如:
FORFILES /?
FORFILES
FORFILES /P C:\WINDOWS /S /M DNS*.*
FORFILES /S /M *.txt /C "cmd /c type @file | more"
FORFILES /P C:\ /S /M *.bat
FORFILES /D -30 /M *.exe
/C "cmd /c echo @path 0x09 在 30 前就被更改。"
FORFILES /D 2001-01-01
/C "cmd /c echo @fname 在 2001年1月1日就是新的。"
FORFILES /D +2017-1-20 /C "cmd /c echo @fname 今天是新的。"
FORFILES /M *.exe /D +1
FORFILES /S /M *.doc /C "cmd /c echo @fsize"
FORFILES /M *.txt /C "cmd /c if @isdir==FALSE notepad.exe @file"
綜上所述單靠forfiles命令恐怕無法滿足樓主的要求。
結合dir和for自己寫腳本實作吧。
bat費勁的話改vbs:
Function ShowDateCreated(filespec)
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(filespec)
ShowDateCreated = f.DateCreated
End Function
uj5u.com熱心網友回復:
感謝回答,dir /dc確實可以顯示當前目錄的檔案創建時間。
我理解你的思路是通過這個方式將所有檔案的創建時間取出來然后和當前時間比較,
但是不知道具體如何實作。
請不吝賜教。
VBS腳本看不太懂,關鍵部分可以解釋下嗎?謝謝了
uj5u.com熱心網友回復:
僅供參考:delbefday.cpp// delbefday.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
//#include "delbefday.h"
#include <io.h>
#include <winbase.h>
#include <stdlib.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
//CWinApp theApp;
//using namespace std;
char pathfilename[_MAX_FNAME];
char path[_MAX_FNAME];
char filename[_MAX_FNAME];
char tt[2];
CTime set_time;
void logtofile(CString log) {
FILE *f;
CString tmpstr;
f=fopen("c:\\delbefday.log","a");
tmpstr.Format("%s %s",CTime::GetCurrentTime().Format("%y%m%d %H%M%S"),log);
fprintf(f,"%s\n",tmpstr);
fclose(f);
}
void splitpathfilename(char *pn) {
char *a=strrchr(pn,'\\');
DWORD len=_MAX_FNAME;
if (a==NULL) {
len=GetCurrentDirectory(len,path);
path[len]='\\';
path[len+1]=0;
sprintf(pathfilename,"%s%s",path,pn);
} else {
strncpy(path,pn,a-pn+1);path[a-pn+1]=0;
strcpy(pathfilename,pn);
}
// printf("path,pathfilename=%s,%s\n",path,pathfilename);
}
int delbefday(char *dayb,char *pn) {
struct _finddata_t c_file;
long hFile;
int db,r;
CTime ft;
CString logstr;
sscanf(dayb,"%d",&db);
if (db>=0) {
printf("befdays %d is NOT negative\n",db);
return 3;
}
set_time=CTime::GetCurrentTime();
set_time+=CTimeSpan(db,0,0,0);
splitpathfilename(pn);
if ((hFile=_findfirst(pathfilename,&c_file))==-1L) {
printf("Can not find %s files before %d days\n",pathfilename,-db);
_findclose(hFile);
return 1;
}
r=1;
while (1) {
strcpy(filename,path);strcat(filename,c_file.name);
if (!(c_file.attrib&_A_RDONLY||c_file.attrib&_A_SYSTEM||c_file.attrib&_A_SUBDIR)) {
CTime ftw(c_file.time_write);
CTime fta(c_file.time_access);
CTime ftc(c_file.time_create);
switch (tt[0]) {
case 'W':ft=ftw;break;
case 'A':ft=fta;break;
case 'C':ft=ftc;break;
default:ft=ftw;break;
}
if (set_time>ft) {
if (_unlink(filename)==0) {
strcat(filename," DELETE ok.");
printf("%s\n",filename);
logtofile(filename);
r=0;
} else {
strcat(filename," DELETE failure!");
printf("%s\n",filename);
logtofile(filename);
}
} else {
printf("Skip %s, for not before %d days\n",filename,-db);
}
} else {
printf("Skip %s, for attribute is ReadOnly|System|Directory\n",filename);
}
if (_findnext(hFile,&c_file)!=0) break;//
}
_findclose(hFile);
return r;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int dayb=0,r;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
printf("Fatal Error: MFC initialization failed");
return 4;
}
if (argc<3) {
printf("Delete some specifed files in ONE dir which (Write|Create|Access) datetime before some days(Ignore ReadOnly|System files)\n");
printf("Usage :%s befdays(must negative) DrivePathFileSpec [/T<W|A|C>]\n",argv[0]);
printf("Example:%s -3 D:\\log\\*.log\n",argv[0]);
set_time=CTime::GetCurrentTime();
printf(" Now is %s",set_time.Format("%Y-%m-%d %H:%M:%S\n"));
dayb=-3;
set_time+=CTimeSpan(dayb,0,0,0);
printf(" so this command will\n Delete d:\\log\\*.log which datetime before %s\n",set_time.Format("%Y-%m-%d %H:%M:%S"));
return 2;
}
if (argc>=4) sprintf(filename,"-------------%s %s %s %s----------------",argv[0],argv[1],argv[2],argv[3]);
else sprintf(filename,"-------------%s %s %s----------------",argv[0],argv[1],argv[2]);
logtofile(filename);
tt[0]='W';
tt[1]=0;
if (argc>=4) {
tt[0]=argv[3][strlen(argv[3])-1];
}
_strupr(tt);
if (tt[0]!='A'&&tt[0]!='C') tt[0]='W';
r=delbefday(argv[1],argv[2]);
return r;
}
uj5u.com熱心網友回復:
一言不合放cpp,讓樓主怎么跑來來來,樓主,我給你一個VBS,直接保存運行就行,運行完會得到一個帶串列的批處理檔案,直接運行批處理就能洗掉,還可以打開這個批處理檔案查看洗掉串列
dim SrcDir,DaysAgo
SrcDir="C:\test"
DaysAgo=60
set fso = CreateObject("Scripting.FileSystemObject")
enumFolder(SrcDir)
msgbox "處理完成"
'這個腳本會把指定目錄里(包括子檔案夾)所有60天前的檔案列出來,寫入一個批處理檔案,運行
'批處理就能刪檔案,運行前可以打開這個批處理查看檔案串列
sub enumFolder(folder)
set objFolder = fso.getfolder(folder)
set subFolders = objFolder.subfolders
for each objFile in objFolder.Files
if objFile.DateCreated<(cdate(year(now) & "-" & month(now) & "-" & day(now))-60) then
'if objFile.DateCreated<(now-60) then '上面一句是按年月日去判斷60天之前,這一句是精確到秒去判斷嚴格的60天之前
set outFile = fso.OpenTextFile("output.bat",8,True)
outFile.Write("rem " & objFile.DateCreated & vbcrlf & "delete """ & objFile.path & """" & vbcrlf & vbcrlf)
'outFile.Write("delete """ & objFile.path & """" & vbcrlf) '上一句把檔案的創建日期也打出來了,供比對;這一句只輸出洗掉檔案的批處理陳述句
outFile.Close
end if
next
for each subFolder in subFolders
enumFolder(subFolder)
next
end sub
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/120769.html
標籤:Windows客戶端使用
下一篇:bat腳本 實作檔案內容替換
