You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux环境下禁用XCMD时,如何递归获取SAS数据集创建日期?

纯SAS宏实现无XCMD环境下的目录递归扫描与日期获取

以下是完全基于SAS内部函数和语句实现的方案,无需依赖XCMD或系统命令,可在Linux环境下完成目录递归扫描、提取SAS数据集内部创建日期以及其他文件的修改日期:

步骤1:初始化结果数据集

先创建用于存储扫描结果的空数据集,定义字段类型与长度:

data file_info;
    length dir_path $256 file_name $128 file_type $16 create_date datetime. modify_date datetime.;
    stop;
run;

步骤2:递归扫描宏定义

%macro scan_dir(root_dir);
    %local did i fname full_path fref fid rc libref create_date modify_date;

    /* 打开目标目录,失败则终止当前分支 */
    %let did = %sysfunc(dopen(&root_dir));
    %if &did. = 0 %then %do;
        %put ERROR: 无法访问目录: &root_dir.;
        %return;
    %end;

    /* 遍历目录下所有条目 */
    %let i = 1;
    %let fname = %sysfunc(dread(&did., &i.));
    %do %while(&fname. ne );
        %let full_path = &root_dir./&fname.;

        /* 判断当前条目为目录还是文件 */
        %if %sysfunc(doptname(&did., &i.)) = DIRECTORY %then %do;
            /* 跳过当前目录(.)和上级目录(..),递归扫描子目录 */
            %if &fname. ne . and &fname. ne .. %then %do;
                %scan_dir(&full_path.);
            %end;
        %end;
        %else %do;
            /* 获取文件修改日期 */
            %let fref = TMP_FILE_HANDLE;
            %let fid = %sysfunc(fopen(&fref., &full_path., S));
            %if &fid. > 0 %then %do;
                %let modify_date = %sysfunc(attrn(&fid., MODATE));
                %let rc = %sysfunc(fclose(&fid.));
                %let create_date = .;

                /* 处理SAS数据集文件(.sas7bdat),提取内部创建日期 */
                %if %sysfunc(scan(&fname., -1, .)) = sas7bdat %then %do;
                    %let libref = TMP_LIB;
                    /* 临时挂载目录为SAS库 */
                    %let rc = %sysfunc(libname(&libref., &root_dir.));
                    %if &rc. = 0 %then %do;
                        /* 通过字典表读取数据集创建日期 */
                        proc sql noprint;
                            select crdate into :create_date trimmed
                            from dictionary.tables
                            where libname = upcase("&libref.") 
                              and memname = upcase("%sysfunc(scan(&fname., 1, .))");
                        quit;
                        /* 清理临时库 */
                        %let rc = %sysfunc(libname(&libref., clear));

                        /* 若字典表未找到,尝试直接读取文件头(兼容特殊情况) */
                        %if &create_date. = %then %do;
                            %let fid = %sysfunc(fopen(&fref., &full_path., S, B));
                            %if &fid. > 0 %then %do;
                                /* SAS7BDAT文件头16-23字节为创建时间(8字节整数格式) */
                                %let rc = %sysfunc(fseek(&fid., 16, 0));
                                %let raw_date = %sysfunc(fget(&fid., 8));
                                %let create_date = %sysfunc(inputn(&raw_date., IB8.));
                                %let rc = %sysfunc(fclose(&fid.));
                            %end;
                        %end;
                    %end;
                    %else %do;
                        %put WARNING: 无法挂载目录&root_dir.,无法获取&fname.的创建日期;
                    %end;
                %end;

                /* 将结果写入数据集 */
                proc sql noprint;
                    insert into file_info
                    values ("&root_dir." "&fname." "%sysfunc(scan(&fname., -1, .))" &create_date. &modify_date.);
                quit;
            %end;
            %else %do;
                %put WARNING: 无法打开文件: &full_path.;
            %end;
        %end;

        %let i = %eval(&i. + 1);
        %let fname = %sysfunc(dread(&did., &i.));
    %end;

    /* 关闭目录句柄 */
    %let rc = %sysfunc(dclose(&did.));
%mend scan_dir;

步骤3:调用宏并查看结果

/* 指定要扫描的根目录 */
%scan_dir(/your/target/directory/path);

/* 格式化输出结果 */
proc print data=file_info noobs;
    var dir_path file_name file_type create_date modify_date;
    format create_date modify_date datetime20.;
    title '文件扫描结果';
run;

关键说明

  • 递归扫描逻辑:通过dopen/dread/dclose函数遍历目录,遇到子目录时递归调用自身实现深度遍历
  • SAS数据集创建日期:优先通过临时挂载目录为SAS库,读取dictionary.tables中的crdate字段;若失败则直接读取SAS7BDAT文件头的指定偏移量(兼容多数SAS版本)
  • 普通文件修改日期:通过fopen打开文件后,用attrn函数提取MODATE属性
  • 权限要求:确保SAS进程对目标目录及所有子目录、文件有读取权限

内容的提问来源于stack exchange,提问作者Aamir Warsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 14:53:10