BookmarkSubscribeRSS Feed
june_bug
Fluorite | Level 6

Hi

I would like to add leading or trailing blanks and then export to a text file. The outfile should keep all blanks.

Tx JJ

19 REPLIES 19
Tom
Super User Tom
Super User

Use the $CHAR or $VARYING format when writing the text file.

Note that SAS stores strings as fixed length.  If you wan to append varying numbers of blanks to a character variable then you might need to store your indented length into another variable.  That would come in handy for using $VARYING format as it requires a second variable with the length.

Try this little example.

data example;

   length string $100 len 8 ;

   input @;

   do pre=0 to 3 ;

      do post=0 to 3;

         if pre then string = repeat(' ',pre-1)|| _infile_;

         else string=_infile_;

         len = length(string)+post ;

         put pre= post= '|' string $varying100. len '|' ;

      end;

   end;

cards;

line one

line two

;;;;

june_bug
Fluorite | Level 6

Hi Tom

I already have a dataset that I am using, I only need to include the spaces and export.

Can you help?

JJ

Tom
Super User Tom
Super User

Export to what format?  What does the data look like? 

How do you know when you have trailing spaces?  For example if COMMENT field is defined as length=$100 and the actual value is 10 characters long SAS will store 90 trailing spaces.  Do you want to output all of those 90 trailing spaces?  Or do you want just a subset? If so how do you know how many?

MichaelPearce
Obsidian | Level 7

To embed spaces in an exported TXT file you need to use fopen, fput, write etc., as you will have found SAS strips off leading spaces.

So:

data textTbl;
  str = "      Test     ";
run;

filename zout 'c:\spaces.txt';

data _null_;
  set textTbl end=eof;

  retain fid 0;

  if _n_ eq 1 then
     fid = fopen('zout','O');

  if fid gt 0 then do;
    rc = fput(fid,str);
    rc = fwrite(fid,'P');
  end;

  if eof then
     rc = fclose(fid);
run;

filename zout;

june_bug
Fluorite | Level 6

Hi Tom/Michael

I have the completed date set comprising of three columns, the total characters when exported to text comprises of 81 characters per row. The export will be uploaded into aother system that requires the row/field to have a total of 173 characters including spaces. I need to fill the balance of characters in my dataset with spaces when exported in order for the job to run. The exported 81 characters are fixed so that no will not change.

A simple excercise of just including  5 blanks columns after the first and second column increased the characters to 169 and some to 177.

Tom
Super User Tom
Super User

What format do you want the export file to have?

Normally you would want fixed positions (say variable 1 is in column 1 to 10, variable 2 is in columns 11-20, etc ) or you would be told to separate the fields by commas or some other delimiter.  Because you keep mentioning that you want to maintain the spaces I assume you want fixed postions.

Let's assume you have a dataset named HAVE with variables VAR1 VAR2 and VAR3.

Assume VAR1 is numeric (integer values) add would require 10 spaces to display the largest possible value.  VAR2 is 21 characters and VAR3 is 50.

So the total is 81.  Now to output a file with where every line is exactly 173 characters long you could use a program like.

data _null_;

   file 'exportfile' ;

   set have ;

   put @1 var1 10.  var2 $21. var3 $50. @173 ' ' ;

run;

If your obsession with preserving spaces means the spaces inside the values of the variables use the $CHAR format instead of the $ format when writing the character variables.

To test it read it back in and use the LIST statement.  That will display the lines from the input file and at the end of each line it will show the number of characters.

data _null_;

  infile 'exportfile';

  input;

  list;

run;

june_bug
Fluorite | Level 6

Tx Tom it's seems to be working but still have a few questions.

I  hnow have 4 columns and the 3rd column is surnames. Because the length of these vary it distorts the last column by pushing the next column out. How can I maintain this.

When I run thye first part of code the min and max characters =174

When I run the second part of code the count of the line varies from 80 -88.

Not sure what I am doing wrong.

june_bug
Fluorite | Level 6

TEST1030001010101010 00000162             00000071707MRSJJUMPING       00000001111111111470010205-03-13

TEST1030020202020202 00000162             00000120825MRRFUFUFUFUF    00000000222222222055555105-03-13

TEST1030030303030303 00000162             00000053657MISSLDUDUDUDUD              0000000121212121622105205-03-13



This is an example of the distortion.

Tom
Super User Tom
Super User

If he data is too wide for the space you have allocated then there is nothing you can do. Either you have to truncate the field or shift the location.

Looking at your example data it looks to me like four fields that you want to place at columns 1, 22, 43 and 70.  To me the easiest way to insure this placement is to use @nnn syntax of pointer control when writing the data.

data have ;

  length var1 $20 var2 8 var3 $26 var4 $32 ;

  input var1-var4 ;

cards;

TEST1030001010101010 00000162             00000071707MRSJJUMPING       00000001111111111470010205-03-13

TEST1030020202020202 00000162             00000120825MRRFUFUFUFUF    00000000222222222055555105-03-13

TEST1030030303030303 00000162             00000053657MISSLDUDUDUDUD              0000000121212121622105205-03-13

;;;;

filename out temp;

data _null_;

  set have;

  file out lrecl=173 ;

  put @1 var1

      @22 var2 z8.

      @43 var3

      @70 var4

      @173 ' '

  ;

run;

data _null_;

  infile out;

  input;

  list;

run;


RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0

1         TEST1030001010101010 00000162             00000071707MRSJJUMPING     00000001111111111470010205-03-1

     101  3                                                                         173

2         TEST1030020202020202 00000162             00000120825MRRFUFUFUFUF    00000000222222222055555105-03-1

     101  3                                                                         173

3         TEST1030030303030303 00000162             00000053657MISSLDUDUDUDUD  0000000121212121622105205-03-13

     101                                                                            173

NOTE: 3 records were read from the infile OUT.

      The minimum record length was 173.

      The maximum record length was 173.


june_bug
Fluorite | Level 6

Tx Tom my export is sorted, now I just need to test on the system.

Tx so much for your help!

MichaelPearce
Obsidian | Level 7

Hi June,

I think I went in a little complex to start with, fopen etc.will give you complete control of the output file, but you dont need that level of complexity.

3 columns into 173 characters is much easier to do with the put statement and @ modifiers, it's much more readable code as well, which will make maintenance easier.

For example:

filename zout 'c:\testText.txt';

data _null_;
  set sashelp.cars;

  file zout;

  put @5 make @50 model @100 type @173 ' ';
run;

filename zout;

As you can see the @ sets the starting point of the field and the ' ' at the end just makes the overall width 173 characters.

amhens3
Calcite | Level 5

I'm late to the party, but this is exactly what I needed.  Thanks!

june_bug
Fluorite | Level 6

Michael the last line explaining the @ is  a bit confusing. Is it the starting point of the first character in that column or the start of the ‘blank between the columns.

Is this where you want to position them?

MichaelPearce
Obsidian | Level 7

Hi June,

Indeed the @ is the starting point of the text in a column, the

@173 ' '

Makes a single space column at the end to ensure that the overall line lenght is 173 characters.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 19 replies
  • 26619 views
  • 2 likes
  • 5 in conversation