EagerToLearn
EagerToLearn

Reputation: 675

Prevent SAS to automatically remove trailing blank in string

I have a sample data set like below.

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

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

I want to export this data set to csv (fixed-width format) and every line will has the length of 20 byte (20 1-byte-character).

enter image description here

But SAS auto remove my trailing spaces. So the result would be 17 byte for each line. (the filler is truncated)

I know I can insert the filler like this.

put w_out filler $3.;

But this won't work in case the `site' column is empty, SAS will truncate its column and the result also not be 20 byte for each line.

Upvotes: 3

Views: 2002

Answers (3)

Tom
Tom

Reputation: 51566

You probably do not want to write a fixed column file using a multi-byte character set. Instead look into seeing if your can adjust your process to use a delimited file instead. Like you did in your example input data.

If you want the PUT function to write a specific number of bytes just use formatted PUT statement. To have the number of bytes written vary based on the strings value you can use the $VARYING format. The syntax when using $VARYING is slightly different than when using normal formats. You add a second variable reference after the format specification that contains the actual number of bytes to write.

You can use the LENGTH() function to calculate how many bytes your name values take. Since it normally ignores the trailing space just add another character to the end and subtract one from the overall length.

To pad the end with three blanks you could just add three to the width used in the format for the last variable.

data d01;
  infile datalines dlm='#';
  length Name $15 IdNumber $4 Salary $5 Site $3 ;
  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 $4. Salary $5. Site $6. ;
run;

Results:

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.

Upvotes: 2

SAS2Python
SAS2Python

Reputation: 1297

I didn't quite understand what you are trying to do with ksubstr, but if you want to add padding to get the total length to 20 characters, you may have to write some extra logic:

data _null_ ;
 set d01 ;
 file "/folders/myfolders/test.csv" lrecl=1000 ;
 length filler $20;
 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 ;

Upvotes: 2

mjsqu
mjsqu

Reputation: 5452

By default SAS sets an option of NOPAD on a FILE statement, it also sets each line to 'variable format', which means lengths of lines can vary according to the data written. To explicitly ask SAS to pad your records out with spaces, don't use a filler variable, just:

  • Set the LRECL to the width of file you need (20)
  • Set the PAD option, or set RECFM=F

Sample code:

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

More info here: http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000171874.htm#a000220987

Upvotes: 1

Related Questions