有没有办法在同一数据步骤中立即解析在数据步骤中创建的宏变量?

Is there a way to instantly resolve macro variable created in a data step in the same data step?

背景是我需要使用filename命令来执行grep并将结果作为输入。

这是我的输入数据集 test

firstname   lastname   filename
<blank>     <blank>    cus_01.txt
<blank>     <blank>    cus_02.txt

文件名值是我需要 grep 的实际文件,因为我需要这些文件中的某些字符串来填充名字和姓氏

代码如下:

data work.test;
   set work.test;
   call symputx('file', filename);
   filename fname pipe "grep ""Firstname"" <path>/&file.";
   filename lname pipe "grep ""Lastname"" <path>/&file.";
   infile fname;
   input firstname;
   infile lname;
   input lastname; 
run;

但是,在数据步骤过程完成之前,无法使用在数据步骤中创建的宏变量。所以,这意味着,&file。无法解析,无法在文件名中使用。

有没有办法解析宏变量?

谢谢!

这没有经过测试。您需要使用 INFILE 语句选项 FILEVAR。

data test;
   input (firstname   lastname   filename) (:.);
   cards;
<blank>     <blank>    cus_01.txt
<blank>     <blank>    cus_02.txt
;;;;
   run;

data work.grep;
   set work.test;
   length cmd 8;
   cmd = catx(' ','grep',quote(strip(firstname)),filename);
   putlog 'NOTE: ' cmd=;
   infile dummy pipe filevar=cmd end=eof;
   do while(not eof);
      input;
      *something;
      output;
      end;
   run;

如果您有许多客户文件,使用管道进行 grep 可能是一项昂贵的操作系统操作,并且在 SAS 服务器上可能是不允许的(管道、x、系统等...)

您可以使用 infile 的通配符功能和 filename= 选项在单个数据步骤中读取所有以模式命名的文件,以捕获正在读取的活动文件。

样本:

%let sandbox_path = %sysfunc(pathname(WORK));

* create 99 customer files, each with 20 customers;

data _null_;
  length outfile 5;
  do index = 1 to 99;
    outfile = "&sandbox_path./" || 'cust_' || put(index,z2.) || '.txt';
    file huzzah filevar=outfile;
    putlog outfile=;

    do _n_ = 1 to 20;
      custid+1;
      put custid=;
      put "firstname=Joe" custid;
      put "lastname=Schmoe" custid;
      put "street=";
      put "city=";
      put "zip=";
      put "----------";
    end;
  end;
run;

* read all the customer files in the path;
* scan each line for 'landmarks' -- either 'lastname' or 'firstname';    

data want;
  length from_whence source 8;
  infile "&sandbox_path./cust_*.txt" filename=from_whence ;
  source = from_whence;
  input;

  select;
    when (index(_infile_,"firstname")) topic="firstname";
    when (index(_infile_,"lastname")) topic="lastname";
    otherwise;
  end;

  if not missing(topic);

  line_read = _infile_;
run;