公司要求QC侧程序的运行要在Source侧之后,目前没有专门的工具检查程序运行时间,只能人工核查。但人工核查不仅繁琐,还难免会有疏漏。
于是,我打算写个宏程序来完成这项工作。基于模块化考虑,我先介绍获取文件修改时间的宏程序,后续的时间比较在另行操作。宏程序代码附在文章末尾。
获取文件修改时间的主要思路是,通过电脑的CMD指令获取文件的修改时间,然后将指令的返回结果读入SAS数据集。
1. CMD指令获取文件修改时间
以Win10系统为例,进行演示。Linux系统操作可能不同,后续研究再介绍。
首先,在搜索栏输入CMD,打开命令提示符。
获取文件夹的所用的命令是dir
,我们可以输出dir /?
查看该命令的帮助文档。
dir /?
在文档中可以发现,查看文件的时间相关信息,使用的是/t
选项。选项有3个参数,分别对应创建时间、上次访问时间以及上次写入时间。
我测试了下,省略参数时,默认输出是上次写入时间,也就是想要获取的文件修改时间。
我新建了个Test文件夹,文件夹中包含SAS程序和SAS log文件。
获取该文件夹下所有Log文件的修改时间的命令如下:
dir /t E:\99_Test\SDTM\*.log
*
为通配符,可以匹配所有后缀为.log
的文件。
命令的输出结果如下:
该文件夹中,所有Log文件的修改时间都显示出来了,后面需要将这些结果读入到SAS中。
2. 将CMD返回结果导入SAS数据集
在SAS中,可以使用filename
语句建立一个文件引用,与CMD指令的输出结果相关联。同时,必须使用pipe
选项,SAS才能访问访问CMD指令的输出结果。
*Create a fileref for the files Modified datetime;
filename cmd pipe "dir /t E:\99_Test\SDTM\*.log";
文件引用建立好之后,在Data步中使用infile
语句进行读取。考虑到输出结果中有4列内容,提前设置好保存这些结果的变量长度,避免截断。
*Read the fileref;
data tmp;
length date $20 time $20 size $200 filenam $20 ;
infile cmd;
input date $ time $ size $ filenam $;
run;
从结果中可以出,有一些多余的信息出现在读入数据集中前两行,和后两行。我们可以在Data步中进行移除,同时进行变量处理, 方便结果查看。
*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;
整理结果如下,该文件夹下的Log文件的修改时间输出完毕。
3. 汇总宏程序
流程跑通之后,将程序整理成宏。
宏程序与前面代码相比,多了对路径宏参数的处理。因为输入路径时,并非所有人都习惯以斜杠\
结尾,所以直接将斜杠写在Filename
语句的路径中。
如果输入的宏参数多了斜杠,直接在宏程序的开头移去。这样就避免了路径输入不统一对宏运行的影响。
%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
);
总结
文章介绍了,通过SAS读取CMD命令的返回结果,获取文件夹中特定类型文件的修改时间。
目前以上程序适用于win10系统,如果电脑系统语言为中文,指令输出结果中包含中文字符。如果当前SAS编码环境不支持中文,则会导入错误。
最后贴一下,我演示用的SAS中文的编码设置:
%put %sysfunc(getoption(encoding));
%put %sysfunc(getoption(locale));
英文版的编码设置如下,可以正常导入CMD结果。
SAS EG编码设置如下,无法正常导入CMD指令结果:
感谢阅读!若有疑问,欢迎评论区交流!