BookmarkSubscribeRSS Feed
Walternate
Obsidian | Level 7

Hi all,

 

I'm using this sequence to read in a series of SAS programs:

 

%macro run_loop;
    %do i=1 %to &cntlist.;
        %let in_prg=%scan(&varlist.,&i.);
        %let fldr_id = %scan(&dirlist., &i., '^');
 
 
        *------------------------------------------------------------------;
        *------------------------------------------------------------------;
        * READ IN EACH PROGRAM AND REPLACE OLD PURPOSE WITH NEW PURPOSE
        *------------------------------------------------------------------;
        *------------------------------------------------------------------;
 
/*READ IN EACH PROGRAM*/
        data prg_desc_&i.;       
 
 
            infile "&fldr_id.\&in_prg..sas" lrecl=32767 pad;
 
            input intext $char32767.;
            line_counter + 1;
 
            if intext ne ' ';

run;

 


%end;

 

 

%mend run_loop;
%run_loop;

 

I want the data files built using the programs to retain all of the underlying formatting (spaces, tabs, etc.) . There is SOME of that (ie, it's not left aligned) but it does look different from the actual program, which has many more spaces, tabs, etc. on each line. 

 

For example, when I open the program I see:

 

PURPOSE: ABC

                      DEF

                      GHI

 

But when I run my program, it's not so spaced out:

 

PURPOSE: ABC

                    DEF

              GHI

 

Is there a way to set this up so my read-in gives me the exact underlying program line values with all formatting intact?

 

Thanks in advance!

3 REPLIES 3
Quentin
Super User

Is it possible your .sas program has leading tabs on some lines and leading spaces on others?

 

Without getting into the war of tabs vs spaces in code, if you have tab characters in your code, they will be interpreted differently depending on the application you use to open them.

 

You might also want to describe the big picture of what you're doing, as people might have other ideas.  Are you planning to read the code from a .sas file into a data set, and then use a DATA step to update the code, and then write a new .sas file?

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
Tom
Super User Tom
Super User

You need to explain more what you mean.

 

Are you talking about the values of the variable INTEXT that you are creating with this line:

 input intext $char32767.;

How are you LOOKING at the values? 

Did you write them back out to a NEW file?  If so what code did you use?

Did you use PROC PRINT?  If so what output destination did you use? ODS does not not normally preserve leading spaces or use FIXED WIDTH fonts.

 

Did you accidentally allow the original programs to be created with embedded TAB characters?  What text editor did you use to create those original programs?  What tab stop settings did you have in place when editing the files?

 

 

Tom
Super User Tom
Super User

Get it to work properly for single files before trying to wrap it into macro code.  Whether the results "look" right or not is not related to the macro logic you showed.

 

Why did you throw away the empty lines?  Do you not want them in the end result?  If you need the empty lines it is easier to keep them than they to add them back when writing the results back out.  Make sure to use COMPRESS=YES and it does not really have much impact on the filesize to include the empty lines.

 

Why are you using PAD instead of TRUNCOVER on your INFILE statement?  Or since you seem to want the whole line why not just use the automatic _INFILE_ variable?

 

Do you care about trailing spaces on the lines?  If you do then you will need to update your input step to remember how long the source lines were.

data prg_desc_&i.(compress=yes);   
  length line_counter linesize 8 intext $32767 ;  
  line_counter + 1;
  infile "&fldr_id.\&in_prg..sas" lrecl=32767 length=ll ;
  input;
  linesize=ll;
  intext=_infile_;
run;

When writing the lines back out use $CHAR or $VARYING format to preserve the leading spaces.

data _null_;
  set prg_desc_&i. ;
  file NEWFILE lrecl=32767 ;
  put intext $varying32716. linesize;
run;

If you don't need to preserve the trialing spaces (and why would you in a program file??) then calculate LINESIZE using the LENGTHN() function.

data _null_;
  set prg_desc_&i. ;
  file NEWFILE lrecl=32767 ;
  linesize=length(intext);
  put intext $varying32716. linesize;
run;

 

And if it turns out your original issue is just to do with tabs in the source code then you might want to use the EXPANDTABS option of the INFILE statement when reading the files.  But be careful because programmers that allow TAB characters in their programs might also allow tab characters inside the string literals in their code.  I have seen a lot of questions being asked on this forum about when code to read a tab delimited file written with DLM=' ' (where there is a literal TAB character inside the quotes) fails to work when run from SAS Display Manager.  It is because Display Manager knows to replace tabs with spaces before submitting the code to the SAS compiler to run.

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

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
  • 3 replies
  • 419 views
  • 0 likes
  • 3 in conversation