SAS读取含变音符号的DOS文件名时出现编码异常问题
解决SAS读取含变音符号的DOS目录文件名问题
问题根源
DOS的dir命令输出采用OEM字符编码(如CP850),而SAS默认使用ANSI编码(如Windows-1252),两种编码对变音符号的映射规则不同,导致读取后字符显示异常,甚至同一符号出现多种显示形式。
解决方案
方法一:编码匹配与转码
通过指定SAS读取管道输出时使用DOS的OEM编码,再转码为数据库兼容的编码(如UTF-8):
/* 指定管道输出的编码为DOS的CP850 */ filename DIRLIST pipe "dir C:\Z_Backup\LwX\SAS\FilingList\UMLAUTE\ /s" encoding='cp850'; DATA database ; length RawOutput $256 RawOutput_UTF8 $256; infile dirlist length=reclen encoding='cp850'; input RawOutput $varying256. reclen ; /* 提取完整路径(需根据dir输出格式调整,这里假设路径行包含完整地址) */ if index(RawOutput, ':') then do; /* 转码为UTF-8,适配数据库存储 */ RawOutput_UTF8 = encode(trim(RawOutput), 'utf-8', 'cp850'); end; RUN; PROC PRINT data=database; var RawOutput RawOutput_UTF8; RUN;
方法二:使用SAS内部函数遍历目录(推荐)
避免依赖外部DOS命令,直接用SAS的目录操作函数读取原始文件名,彻底解决编码问题:
%macro list_files(root_dir); %local did i fname fpath rc; /* 打开目标目录 */ %let did = %sysfunc(dopen(&root_dir)); %if &did = 0 %then %do; %put ERROR: 无法打开目录 &root_dir; %return; %end; /* 遍历目录内的所有条目 */ %do i = 1 %to %sysfunc(dnum(&did)); %let fname = %sysfunc(dread(&did, &i)); %let fpath = &root_dir\&fname; /* 判断是文件则存入数据集 */ %if %sysfunc(fileexist(&fpath)) %then %do; data _temp; length full_path $256; full_path = "&fpath"; run; proc append base=database data=_temp force; run; proc delete data=_temp; run; %end; /* 判断是子目录则递归遍历 */ %else %if %sysfunc(dexist(&fpath)) %then %do; %list_files(&fpath); %end; %end; /* 关闭目录句柄 */ %let rc = %sysfunc(dclose(&did)); %mend; /* 初始化存储结果的数据集 */ data database; length full_path $256; stop; run; /* 调用宏遍历目标目录 */ %list_files(C:\Z_Backup\LwX\SAS\FilingList\UMLAUTE) /* 查看最终结果 */ PROC PRINT data=database; RUN;
说明
- 方法二无需处理编码转换,直接读取系统原生文件名,完美支持变音符号(ä,ê,ö,ü,ß等),且能直接获取完整路径,稳定性更高。
- 若使用方法一,需根据
dir命令的输出格式调整路径提取逻辑,确保只保留有效文件路径行。
内容的提问来源于stack exchange,提问作者Lub Ben Ja
相关产品推荐
相关产品推荐

