SAS:在代码中分解长字符串

时间:2016-10-12 15:45:56

标签: sas

我觉得将代码限制在每行80个字符以内是一种好习惯。由于SAS忽略了空白区域,因此这通常不是问题。但是,我偶尔需要引用一些过长的字符串。

例如,

filename infile "B:\This\file\path\is\really\long\but\there\is\nothing\I\can\do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck\with\whatever\organization\or\lack\thereof\exists\for\directory\hierarchies\filename.txt";

我可以想到两个解决方案:

1)插入回车。然而,这会使代码看起来非常混乱,并且可能无意中将不可见的字符(即\r\n)引入字符串。

filename infile "B:\This\file\path\is\really\long\but\there\is\nothing\
I\can\do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck\
with\whatever\organization\or\lack\thereof\exists\for\directory\hierarchies\
filename.txt";

2)使用宏变量将字符串分成几个部分。

%let part1 = B:\This\file\path\is\really\long\but\there\is\nothing\;
%let part2 = I\can\do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck\;
%let part3 = with\whatever\organization\or\lack\thereof\exists\for\directory\hierarchies\;
%let part4 = filename.txt;

filename infile "&part1.&part2.&part3.&part4.";

%let path = %sysfunc(pathname(infile));
%put &path;

理想情况下,我希望能够遵循其余代码的缩进方案。

filename infile "B:\This\file\path\is\really\long\but\there\is\nothing\
  I\can\do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck\
  with\whatever\organization\or\lack\thereof\exists\for\directory\hierarchies\
  filename.txt";

至少在本示例的上下文中,可能的解决方案是完全绕过声明并提示输入文件的使用。但是,这似乎不容易实现。

3 个答案:

答案 0 :(得分:2)

对于需要将字符串用作一个标记的这种情况,然后将其拆分为单独的宏变量是最佳方法。

%let basedir=b:\Main Folder;
%let project=This project\has\many\parts;
%let fname=filename.txt ;
...
infile "&basedir/&project/&fname" ;

请注意,SAS很乐意为您自动转换Unix(/)和Windows(\)样式之间的目录分隔符。

您还可以利用fileref指向目录树中的起点。

filename basedir "&basedir";
...
infile basedir("&project/&fname");

您还可以将路径存储在文本文件或数据集中,并使用它来生成宏变量的路径。

data _null_;
  infile 'parameter_file.txt' ;
  input filename :$256. ;
  call symputx('filename',filename);
run;
...
infile "&filename" ;

使用宏变量的另一个变体是使用多个%LET语句来初始化单个宏变量。这样你就可以将长字符串分成多个标记。

%let fname=B:\This\file\path\is\really\long\but\there\is\nothing;
%let fname=&fname\I\can\do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck;
%let fname=&fname\with\whatever\organization\or\lack\thereof\exists\for\directory\hierarchies;
%let fname=&fname\filename.txt;

或者您可以使用DATA步骤来设置宏变量。

data _null_;
  call symputx('fname',catx('\'
    ,'B:\This\file\path\is\really\long\but\there\is\nothing\I\can'
    ,'do\about\it\because\it\is\on\a\shared\network\drive\and\I\am\stuck'
    ,'with\whatever\organization\or\lack\thereof\exists\for\directory'
    ,'hierarchies\filename.txt'
  ));
run;

答案 1 :(得分:0)

对于需要在代码中添加长字符串(例如数据集标签或某种类型的描述)的情况,请考虑使用%cmpres。该函数有限制,但如果可以使用,则可以在80列中保留一列。在这里,我的CR和其他相邻的空白被“压缩”为单个空格字符。

%macro get_filename(FILEPATH_FILE, FILE)
   /DES=%cmpres("returns a file's name, placed into var FILE, removing the 
                 file path from FILEPATH_FILE.");

答案 2 :(得分:0)

如果您经常这样做,请使用%SYSFUNC()和COMPRESS()来创建用户定义的宏,如下所示:

%macro c(text);
  %sysfunc(compress(&text, ,s))
%mend;

filename infile %c("B:\This\file\path\is\really\long\but\there\is\nothing\I\
                    can\do\about\it\because\it\is\on\a\shared\network\drive\
                    and\I\am\stuck\with\whatever\organization\or\lack\thereof\
                    exists\for\directory\hierarchies\and\he\uses\B\as\a\drive\
                    OMG\who\does\that\filename.txt");

%put %c("B:\This\file\path\is\really\long\but\there\is\nothing\I\
         can\do\about\it\because\it\is\on\a\shared\network\drive\
         and\I\am\stuck\with\whatever\organization\or\lack\thereof\
         exists\for\directory\hierarchies\and\he\uses\B\as\a\drive\
         OMG\who\does\that\filename.txt");

COMPRESS()函数中的选项“ s”将删除所有空白字符。

SAS在日志上发布注释,您可以忽略它们:

NOTE: The quoted string currently being processed has become more than 262 characters long.  You might have unbalanced quotation marks.