公司要求QC側(cè)程序的運(yùn)行要在Source側(cè)之后镣奋,目前沒有專門的工具檢查程序運(yùn)行時(shí)間,只能人工核查悉尾。但人工核查不僅繁瑣,還難免會有疏漏挫酿。
于是构眯,我打算寫個(gè)宏程序來完成這項(xiàng)工作≡绻辏基于模塊化考慮惫霸,我先介紹獲取文件修改時(shí)間的宏程序,后續(xù)的時(shí)間比較在另行操作葱弟。宏程序代碼附在文章末尾壹店。
獲取文件修改時(shí)間的主要思路是,通過電腦的CMD指令獲取文件的修改時(shí)間芝加,然后將指令的返回結(jié)果讀入SAS數(shù)據(jù)集硅卢。
1. CMD指令獲取文件修改時(shí)間
以Win10系統(tǒng)為例,進(jìn)行演示藏杖。Linux系統(tǒng)操作可能不同将塑,后續(xù)研究再介紹。
首先蝌麸,在搜索欄輸入CMD点寥,打開命令提示符。
獲取文件夾的所用的命令是dir
来吩,我們可以輸出dir /?
查看該命令的幫助文檔敢辩。
dir /?
在文檔中可以發(fā)現(xiàn)蔽莱,查看文件的時(shí)間相關(guān)信息,使用的是/t
選項(xiàng)戚长。選項(xiàng)有3個(gè)參數(shù)盗冷,分別對應(yīng)創(chuàng)建時(shí)間、上次訪問時(shí)間以及上次寫入時(shí)間历葛。
我測試了下正塌,省略參數(shù)時(shí),默認(rèn)輸出是上次寫入時(shí)間恤溶,也就是想要獲取的文件修改時(shí)間乓诽。
我新建了個(gè)Test文件夾,文件夾中包含SAS程序和SAS log文件咒程。
獲取該文件夾下所有Log文件的修改時(shí)間的命令如下:
dir /t E:\99_Test\SDTM\*.log
*
為通配符鸠天,可以匹配所有后綴為.log
的文件。
命令的輸出結(jié)果如下:
該文件夾中帐姻,所有Log文件的修改時(shí)間都顯示出來了稠集,后面需要將這些結(jié)果讀入到SAS中。
2. 將CMD返回結(jié)果導(dǎo)入SAS數(shù)據(jù)集
在SAS中饥瓷,可以使用filename
語句建立一個(gè)文件引用剥纷,與CMD指令的輸出結(jié)果相關(guān)聯(lián)。同時(shí)呢铆,必須使用pipe
選項(xiàng)晦鞋,SAS才能訪問訪問CMD指令的輸出結(jié)果。
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t E:\99_Test\SDTM\*.log";
文件引用建立好之后棺克,在Data步中使用infile
語句進(jìn)行讀取悠垛。考慮到輸出結(jié)果中有4列內(nèi)容娜谊,提前設(shè)置好保存這些結(jié)果的變量長度确买,避免截?cái)唷?/p>
*Read the fileref;
data tmp;
length date $20 time $20 size $200 filenam $20 ;
infile cmd;
input date $ time $ size $ filenam $;
run;
從結(jié)果中可以出,有一些多余的信息出現(xiàn)在讀入數(shù)據(jù)集中前兩行纱皆,和后兩行湾趾。我們可以在Data步中進(jìn)行移除,同時(shí)進(jìn)行變量處理派草, 方便結(jié)果查看撑帖。
*Keep useful datetime information;
data tmp1;
length folder $200 type $20;
set tmp nobs = nobs;
*remove useless information;
if 2<_n_<nobs-2;
format modifydt e8601dt.;
modifydt = input(strip(date)||"T"||strip(time),e8601dt.);
folder = "E:\99_Test\SDTM\";
type = "log";
keep folder type filenam modifydt;
run;
整理結(jié)果如下,該文件夾下的Log文件的修改時(shí)間輸出完畢澳眷。
3. 匯總宏程序
流程跑通之后胡嘿,將程序整理成宏。
宏程序與前面代碼相比钳踊,多了對路徑宏參數(shù)的處理衷敌。因?yàn)檩斎肼窂綍r(shí)勿侯,并非所有人都習(xí)慣以斜杠\
結(jié)尾,所以直接將斜杠寫在Filename
語句的路徑中缴罗。
如果輸入的宏參數(shù)多了斜杠助琐,直接在宏程序的開頭移去。這樣就避免了路徑輸入不統(tǒng)一對宏運(yùn)行的影響面氓。
%macro modifydt(folder=,type=, outdt=);
*Remove trailing slash;
%if %substr(&folder.,%length(&folder.),1)=\ %then %let folder=%substr(&folder.,1,%length(&folder.)-1);
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t &folder.\*.&type.";
*Read the fileref;
data &outdt.1;
length date $20 time $20 size $200 filenam $20 ;
infile cmd;
input date $ time $ size $ filenam $;
run;
*Keep useful datetime information;
data &outdt.;
length folder $200 type $20;
set &outdt.1 nobs = nobs;
*remove useless information;
if 2<_n_<nobs-2;
format modifydt e8601dt.;
modifydt = input(strip(date)||"T"||strip(time),e8601dt.);
folder = "&folder.";
type = "&type.";
keep folder type filenam modifydt;
run;
%mend modifydt;
%modifydt(
folder=%str(E:\99_Test\SDTM\)
,type=log
,outdt=log
);
總結(jié)
文章介紹了兵钮,通過SAS讀取CMD命令的返回結(jié)果,獲取文件夾中特定類型文件的修改時(shí)間舌界。
目前以上程序適用于win10系統(tǒng)掘譬,如果電腦系統(tǒng)語言為中文,指令輸出結(jié)果中包含中文字符呻拌。如果當(dāng)前SAS編碼環(huán)境不支持中文葱轩,則會導(dǎo)入錯誤。
最后貼一下藐握,我演示用的SAS中文的編碼設(shè)置:
%put %sysfunc(getoption(encoding));
%put %sysfunc(getoption(locale));
英文版的編碼設(shè)置如下靴拱,可以正常導(dǎo)入CMD結(jié)果。
SAS EG編碼設(shè)置如下猾普,無法正常導(dǎo)入CMD指令結(jié)果:
感謝閱讀袜炕!若有疑問,歡迎評論區(qū)交流初家!