BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Leo9
Quartz | Level 8

Hi All,

 

I need to put all SAS program names in one file and in one line. I already have list of program names in a file. I need to create a simple txt file and put program names like this

 

abc.sas xyz.sas abc2.sas etc. 

 

How can you achieve this with put and infile statement ? 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Then try this:

%dirtree(/space/kstr395/brim/misc/programs)
data _null_;
  set dirtree;
  if index(filename,'.') and lowcase(scan(filename,-1,'.'))='sas';
  file "/space/kstr395/brim/misc/programs/batch.txt" recfm=n ;
  put filename;
run;

View solution in original post

13 REPLIES 13
Reeza
Super User

How is the file you already have structured? Can you show an example?

 

This question shows how to create a text file from a SAS data set as a single line.

 

  • Change the file extension to txt
  • Change the delimiter to space
  • Remove DSD option (not needed)
  • Remove END option (not used)
  • Assumes Have is the list of program names
data _null_;
file "test.txt" recfm=N dlm=' ' lrecl=500000;
set have;
put (_all_)(:) +(-1) @;
run;

@Leo9 wrote:

Hi All,

 

I need to put all SAS program names in one file and in one line. I already have list of program names in a file. I need to create a simple txt file and put program names like this

 

abc.sas xyz.sas abc2.sas etc. 

 

How can you achieve this with put and infile statement ? 

 

 


 

Leo9
Quartz | Level 8

Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names. 

Tom
Super User Tom
Super User

@Leo9 wrote:

Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names. 


Your description is backwards.  

 

You cannot use a text file to put names.  You use SAS code to put the names into the text file.

 

The program shown was creating a text file.  It assumed you had the list of filenames in a dataset.

 

So let's assume you have dataset named PROGRAMS which has a variable named FILENAME and you want to create a file named 'program_names.txt'.  Then this program will write one line to the file with a space between each filename.

data _null_;
  file 'program_names.txt';
  set programs;
  put filename @ ;
run;

If the filenames might have spaces in them then perhaps you want to add the DSD and DLM option to the file statement.  That way SAS will quote the names of any files that have spaces in them.  Otherwise the list would be confusing.

data _null_;
  file 'program_names.txt' dsd dlm=' ';
  set programs;
  put filename @ ;
run;

 

Reeza
Super User

@Leo9 wrote:

Thank you. In your example there has to be a text file already created to put the program names. I want to create a txt file within the program itself (without manually creating it) and then use that text file to put the program names. 


No, there needs to be a SAS data set with the program names. 

 

Where are the program names? Do you need to look through a folder and file all files? Or something else. 

 

Please explain what this means from your original post:

I already have list of program names in a file

Leo9
Quartz | Level 8

Hi All,

 

Thank you for your responses. I should have been more clearer in my original post.  Basically, I am reading names of all the sas programs from a given directory and then I am trying to put them in a text file. 

 

- First read all program names 

- Put all these program names in a text file


Here is the full code

 

filename mybatch "/space/kstr395/brim/misc/programs/batch.txt";


%macro list_files(dir,ext);
%local filrf rc did memcnt name i;
%let rc=%sysfunc(filename(filrf,&dir));
%let did=%sysfunc(dopen(&filrf));

%if &did eq 0 %then %do;
%put Directory &dir cannot be open or does not exist;
%return;
%end;

data _null_ ;
file  "/space/kstr395/brim/misc/programs/batch.txt" recfm=N dlm=' ' lrecl=500000;

%do i = 1 %to %sysfunc(dnum(&did));
%let name=%qsysfunc(dread(&did,&i));
%if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then %do;
%put &dir/&name @@;

put &name @@ ;
%end;
%else %if %qscan(&name,2,.) = %then %do;
%list_files(&dir/&name,&ext)
%end;
%end;
run;

%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(filrf));

%mend list_files;
%list_files( %str(/space/kstr395/brim/misc/programs),sas) ;

 

I am getting an error "Data Step Component Object Failure. Aborted during compilation phase" 

 

Tom
Super User Tom
Super User

Why do you have all of that macro code in there?  You are already running a data step so just call the functions directly.

%macro list_files(dir,ext,file);
data _null_;
  length filrf $8 ;
  rc=filename(filrf,"&dir");
  did=dopen(filrf);
  if did=0 then do;
     putlog "ERROR: Directory &dir cannot be open or does not exist";
     stop;
  end;
  file &file recfm=N ;
  do i=1 to dnum(did);
    length name $256;
    name=dread(did,i);
    if index(name,'.') and lowcase(scan(name,-1,'.'))=lowcase("&ext") then do;
      put name ;
    end;
  end;
  rc = dclose(did);
  rc = filename(filrf);
run;
%mend list_files;

filename mybatch "/space/kstr395/brim/misc/programs/batch.txt";
%list_files(dir=/space/kstr395/brim/misc/programs,ext=sas,file=mybatch)

 

Quentin
Super User

If you remove all the DATA step code, does the macro work?  i.e. as a recursive directory crawler that %PUTs to the log a list of the .sas files found, does that work?  I would start by getting that to work, before trying to adapt it to save results in a file.

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

If you want to traverse a whole subdirectory tree then use something like this.

https://github.com/sasutils/macros/blob/master/dirtree.sas

 

But then you have to decide how you want to write the names into the file. 

Do you want to ignore the directory name? 

program1.sas program2.sas program1.sas program2.sas

Do you want to write the subdirectory name also?

program1.sas program2.sas subdir/program1.sas subdir/program2.sas

Does that include the top level directory name also? 

/top/program1.sas /top/program2.sas /top/subdir/program1.sas /top/subdir/program2.sas
Leo9
Quartz | Level 8

Thank you for your response. I just want program name like 

 

program1.sas program2.sas program1.sas program2.sas
Tom
Super User Tom
Super User

Then try this:

%dirtree(/space/kstr395/brim/misc/programs)
data _null_;
  set dirtree;
  if index(filename,'.') and lowcase(scan(filename,-1,'.'))='sas';
  file "/space/kstr395/brim/misc/programs/batch.txt" recfm=n ;
  put filename;
run;
Leo9
Quartz | Level 8

Thank you! This solution works too. The macro is really great. 

Leo9
Quartz | Level 8

Thank you so much, this works.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 13 replies
  • 832 views
  • 2 likes
  • 5 in conversation