公司要求QC側(cè)程序的運行要在Source側(cè)之后,目前沒有專門的工具檢查程序運行時間,只能人工核查。但人工核查不僅繁瑣,還難免會有疏漏。
于是,我打算寫個宏程序來完成這項工作。基于模塊化考慮,我先介紹獲取文件修改時間的宏程序,后續(xù)的時間比較在另行操作。宏程序代碼附在文章末尾。
獲取文件修改時間的主要思路是,通過電腦的CMD指令獲取文件的修改時間,然后將指令的返回結(jié)果讀入SAS數(shù)據(jù)集。
1. CMD指令獲取文件修改時間
以Win10系統(tǒng)為例,進行演示。Linux系統(tǒng)操作可能不同,后續(xù)研究再介紹。
首先,在搜索欄輸入CMD,打開命令提示符。
獲取文件夾的所用的命令是dir
,我們可以輸出dir /?
查看該命令的幫助文檔。
dir /?
在文檔中可以發(fā)現(xiàn),查看文件的時間相關(guān)信息,使用的是/t
選項。選項有3個參數(shù),分別對應(yīng)創(chuàng)建時間、上次訪問時間以及上次寫入時間。
我測試了下,省略參數(shù)時,默認輸出是上次寫入時間,也就是想要獲取的文件修改時間。
我新建了個Test文件夾,文件夾中包含SAS程序和SAS log文件。
獲取該文件夾下所有Log文件的修改時間的命令如下:
dir /t E:\99_Test\SDTM\*.log
*
為通配符,可以匹配所有后綴為.log
的文件。
命令的輸出結(jié)果如下:
該文件夾中,所有Log文件的修改時間都顯示出來了,后面需要將這些結(jié)果讀入到SAS中。
2. 將CMD返回結(jié)果導(dǎo)入SAS數(shù)據(jù)集
在SAS中,可以使用filename
語句建立一個文件引用,與CMD指令的輸出結(jié)果相關(guān)聯(lián)。同時,必須使用pipe
選項,SAS才能訪問訪問CMD指令的輸出結(jié)果。
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t E:\99_Test\SDTM\*.log";
文件引用建立好之后,在Data步中使用infile
語句進行讀取。考慮到輸出結(jié)果中有4列內(nèi)容,提前設(shè)置好保存這些結(jié)果的變量長度,避免截斷。
*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步中進行移除,同時進行變量處理, 方便結(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文件的修改時間輸出完畢。
3. 匯總宏程序
流程跑通之后,將程序整理成宏。
宏程序與前面代碼相比,多了對路徑宏參數(shù)的處理。因為輸入路徑時,并非所有人都習慣以斜杠\
結(jié)尾,所以直接將斜杠寫在Filename
語句的路徑中。
如果輸入的宏參數(shù)多了斜杠,直接在宏程序的開頭移去。這樣就避免了路徑輸入不統(tǒng)一對宏運行的影響。
%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é)果,獲取文件夾中特定類型文件的修改時間。
目前以上程序適用于win10系統(tǒng),如果電腦系統(tǒng)語言為中文,指令輸出結(jié)果中包含中文字符。如果當前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ū)交流!