如何在SAS中的管道后将特殊字符放入字符串中

How to put special chars in a string after pipe in SAS

我正在将一些 SAS 软件从服务器 Unix 迁移到服务器 Linux。

目前,在 SAS 程序中,我有以下指令:

Filename myname pipe "ls -le &mypath." ;

(然后文件 mynamedata 步骤中用作 InFile myname truncover end=fine;)。

Unix 的 ls 中的选项 -e 生成始终打印年份的文件列表,即使是最近创建的文件也是如此。

例如比较:

myserver.myuser:/mypath> ls -l myfile
-rwxr-xr-x   1 auser   auser   24422893965 Nov  5 06:17 myfile

与:

myserver.myuser:/mypath> ls -le myfile
-rwxr-xr-x   1 auser   auser   24422893965 Nov  5 06:17:27 2021 myfile

在Linux中,ls的选项-e不存在,但是用命令

可以得到相同的结果
ls -l --time-style="+%b %d %T %Y"

问题是如何在SAS指令中使用这个包含%等特殊字符的命令。

我试过:

Filename itt pipe "ls -l --time-style='+%%b %%d %%T %%Y' &mypath." ;

但我得到:

total 1420
-rwxrwxr-x 1 myuser mygroup 1450000 052130864ov %d %T %Y myfile

我试过了:

Filename itt pipe "ls -l --time-style='+%str(%)b %str(%)d %str(%)T %str(%)Y' &mypath." ;

但我明白了

total 1420
-rwxrwxr-x 1 myuser mygroup 1450000 )b )d )T )Y myfile

有没有办法使该命令起作用?

欢迎使用任何替代解决方案来获得相同的结果。

使用%nrstr。这不会在编译时解决 % 标志。

Filename itt pipe "ls -l --time-style='%nrstr(+%b %d %T %Y)' &mypath.";

在 SAS 代码中处理包含宏触发字符 &% 的字符串比在宏代码中要容易得多。

如果您真的想定义文件引用 MYNAME,您可以在数据步骤中使用 FILENAME() 函数调用。或者使用 QUOTE() 函数生成一个在外部带有单引号的宏变量,以保护您可以在 FILENAME 语句中使用的宏触发器。

data _null_;
  length cmd 0;
  cmd = catx(' ','ls -l --time-style="+%b %d %T %Y"',"&mypath");
  call symputx('lscmd',quote(trim(cmd),"'"));
run;
filename myname pipe &lscmd;

但为什么不将 ls 命令构建为读取结果的数据步骤的一部分呢?您还可以为日期时间值使用一种 SAS 更容易阅读的样式,例如 DATETIME 信息格式可以理解的样式。

data ls_output;
  length cmd 0;
  cmd = catx(' ','ls -l --time-style="+%d%b%Y:%T"',"&mypath");
  infile lscmd pipe filevar=cmd truncover ;
  input mode :. links owner :. group :. size lastmod :datetime. file 6.;
  format lastmod datetime19.;
run;