防止 SAS 自动删除字符串中的尾随空白

Prevent SAS to automatically remove trailing blank in string

我有如下示例数据集。

data d01;
   infile datalines dlm='#';
   input Name & . IdNumber & . Salary & . Site & .;
   datalines;
アイ# 2355# 21163# BR1
アイウエオ# 5889# 20976# BR1
カキクケ# 3878# 19571# BR2
;

data _null_ ;
 set d01 ;
 file "/folders/myfolders/test.csv" lrecl=1000 ;
 length filler ;
 filler = '   ';
 w_out = ksubstr(Name, 1, 5) || IdNumber || Salary || Site || filler;
 put w_out;
run ;

我想将此数据集导出为 csv(固定宽度格式),每行的长度为 20 字节(20 个 1 字节字符)。

但是 SAS 自动删除了我的尾随空格。所以结果将是每行 17 个字节。 (填充被截断)

我知道我可以像这样插入填充物。

put w_out filler .;

但是如果“站点”列为空,这将不起作用,SAS 将截断其列并且结果也不是每行 20 个字节。

默认情况下,SAS 在 FILE 语句上设置选项 NOPAD,它还将每行设置为 'variable format',这意味着行的长度可以根据写入的数据而变化.要明确要求 SAS 用空格填充您的记录,请不要使用填充变量,只需:

  • LRECL设置为您需要的文件宽度(20)
  • 设置PAD选项,或设置RECFM=F

示例代码:

data _null_ ;
 set d01 ;
 file "/folders/myfolders/test.csv" lrecl=20 PAD;
 w_out = Name || IdNumber || Salary || Site;
 put w_out;
run ;

更多信息在这里:http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000171874.htm#a000220987

我不太明白你想用 ksubstr 做什么,但如果你想添加填充以使总长度达到 20 个字符,你可能需要编写一些额外的逻辑:

data _null_ ;
 set d01 ;
 file "/folders/myfolders/test.csv" lrecl=1000 ;
 length filler ;
 w_out = ksubstr(Name,1,5) || IdNumber || Salary || Site;

 len = 20 - klength(w_out) - 1;
 put w_out @;
 if len > 0 then do;
   filler = repeat(" ", len);
   put filler $varying20. len;
 end;
 else put;
run ;

您可能不想使用多字节字符集编写固定列文件。相反,看看你是否可以调整你的过程来使用分隔文件。就像您在示例输入数据中所做的那样。

如果您希望 PUT 函数写入特定数量的字节,只需使用格式化的 PUT 语句。要使写入的字节数根据字符串值而变化,您可以使用 $VARYING 格式。使用 $VARYING 时的语法与使用普通格式时的语法略有不同。在包含要写入的实际字节数的格式规范之后添加第二个变量引用。

您可以使用 LENGTH() 函数来计算名称值占用的字节数。因为它通常会忽略尾随 space 只需在末尾添加另一个字符并从总长度中减去一个字符。

要用三个空格填充末尾,您只需在最后一个变量的格式中使用的宽度上加三个。

data d01;
  infile datalines dlm='#';
  length Name  IdNumber  Salary  Site  ;
  input Name -- Site;
datalines;
アイ# 2355# 21163# BR1
アイウエオ# 5889# 20976# BR1
カキクケ# 3878# 19571# BR2
Sam#1#2#3
;

filename out temp;
data _null_;
  set d01;
  file out;
  nbytes=length(ksubstr(name,1,5)||'#')-1;
  put name $varying15. nbytes IdNumber . Salary . Site . ;
run;

结果:

67    data _null_ ;
68      infile out;
69      input ;
70      list;
71    run;

NOTE: The infile OUT is:
      Filename=...\#LN00059,
      RECFM=V,LRECL=32767,File Size (bytes)=110,
      Last Modified=15Aug2019:09:01:44,
      Create Time=15Aug2019:09:01:44

RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0
1         アイ   235521163BR1    24
2         アイウエオ588920976BR1    30
3         カキクケ 387819571BR2    28
4         Sam  1   2    3      20
NOTE: 4 records were read from the infile OUT.
      The minimum record length was 20.
      The maximum record length was 30.