BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
User12
Obsidian | Level 7

Hi Guys,

I have an input sas program where i have all my libnames declared.I am reading that into a sas dataset.while doing that its reading commented out values too.And i don't want those commented code into my sas dataset.

I would like to remove the comments from my dataset whether the comments are made in one single line or multiple lines.

 

the code looks like this:

 

Libname sample1 "XYZ";

Libname sample2 "ABC";

/*Libname sample3 "asdfghjj";*/

Libname sample4 "uxcvdgh";

/*commented out

Libname sample5 "XYZasdf";

Libname sample6 "XYZasdfgb";**/

Libname sample7 "XYZdefrgevsdc";

 

Requirement:Without editing the source file i.e., above sample code i would like the output like this in sas dataset:

obs var1

1      Libname sample1 "XYZ"

2      Libname sample2 "ABC"

3      Libname sample4 "uxcvdgh"

4      Libname sample7 "XYZdefrgevsdc";

 

 

Thanks For the Help

1 ACCEPTED SOLUTION

Accepted Solutions
ChrisNZ
Tourmaline | Level 20

Like this?

data HAVE;
  input STATEMENT $80.;
cards4;
Libname sample1 "XYZ";
Libname sample2 "ABC";
/*Libname sample3 "asdfghjj";*/
Libname sample4 "uxcvdgh";
/*commented out
Libname sample5 "XYZasdf";
Libname sample6 "XYZasdfgb";**/
Libname sample7 "XYZdefrgevsdc";
;;;;
run;

data WANT;
  set HAVE;
  if STATEMENT =:'/*' then COMMENT+1;
  if not COMMENT then output;
  if reverse(trim(STATEMENT))  =:'/*' then COMMENT=0;
  keep STATEMENT;
run;

 

View solution in original post

12 REPLIES 12
ChrisNZ
Tourmaline | Level 20

Like this?

data HAVE;
  input STATEMENT $80.;
cards4;
Libname sample1 "XYZ";
Libname sample2 "ABC";
/*Libname sample3 "asdfghjj";*/
Libname sample4 "uxcvdgh";
/*commented out
Libname sample5 "XYZasdf";
Libname sample6 "XYZasdfgb";**/
Libname sample7 "XYZdefrgevsdc";
;;;;
run;

data WANT;
  set HAVE;
  if STATEMENT =:'/*' then COMMENT+1;
  if not COMMENT then output;
  if reverse(trim(STATEMENT))  =:'/*' then COMMENT=0;
  keep STATEMENT;
run;

 

User12
Obsidian | Level 7
Hi @ChrisNZ that was really good code that helped me out thanks for the help.
Have a question for you
What if i have situation where i have a dlm=";" option set while reading the inputs.How can i solve that situation.

Thanks
ChrisNZ
Tourmaline | Level 20

 

dlm=';'

makes no difference.

 

 

data _null_;
  input STATEMENT $80.;
  file "%sysfunc(pathname(work))\t.txt";
  put STATEMENT; 
cards4;
Libname sample1 "XYZ";
Libname sample2 "ABC";
/*Libname sample3 "asdfghjj";*/
Libname sample4 "uxcvdgh";
/*commented out
Libname sample5 "XYZasdf";
Libname sample6 "XYZasdfgb";**/
Libname sample7 "XYZdefrgevsdc";
;;;;
run;

data WANT;
  infile "%sysfunc(pathname(work))\t.txt" pad dlm=';';
  input STATEMENT $80.;
  if STATEMENT =:'/*' then COMMENT+1;
  if not COMMENT then output;
  if reverse(trim(STATEMENT))  =:'/*' then COMMENT=0;
  keep STATEMENT;
run;

NOTE: The data set WORK.WANT has 4 observations and 1 variables.

User12
Obsidian | Level 7
Hi @ChrisNZ i am using dlm while reading the data i.e., in data _null_ in this case.

Thanks
ChrisNZ
Tourmaline | Level 20
User12
Obsidian | Level 7

Hi @ChrisNZ i have a delimiter set while reading the libname statements into a dataset.

i.e.,  the dlm is set in first data step itself not in WANT Data step.

thanks

ChrisNZ
Tourmaline | Level 20

That's what I do in my second example, isn't it?

 

I use  dlm=';'  to read the data from an external file into a data set.

Sven111
Pyrite | Level 9

I don't know if that's possible, at least not without some modifications to the source file, although I'd be interested to be proven wrong. (Edited to Add: Proven wrong before I even finished posting, that's gotta be a record! Interesting code @ChrisNZ, I'll have to remember that.)

 

I think the bigger question is why do you need to import your SAS code into a dataset?  What are you actually trying to accomplish?  If my assumption is correct and it's something other than just having a dataset containing parts of your SAS code, there may be a better way to go about it.

User12
Obsidian | Level 7

hi @Sven111  i have multiple files where mt libnames are declared.i want to store all of them in one single dataset to keep track of the locations

Sven111
Pyrite | Level 9

Are they ones you use on a regular basis or more long-term ones that you just want to track?  If it's the former you could just declare them once in your SAS autoexec file so they'll be setup for whatever code your running, I have several LIBNAMES setup like that in my autoexec so I can easily reference them from EntGuide or base SAS.  If it's for long-term tracking I still think a dataset isn't necessarily the best way to go, honestly I think just maintaining them in one or more text files may be better and more flexible.  You could even source them using an %INCLUDE statement later on if you wanted to call them again.  It's not as automated, but unless you're dealing with hundreds or thousands of LIBNAMES it's probably the way I'd go.  

 

Plus while @ChrisNZ's code handles the examples you've provided very well, as it stands I doesn't look like it will be able to detect comments if the comment delimiters aren't at the beginning and end of the line (excluding whitespace) or detect the single line comment style.  This may or may not be a problem depending on the coding style of the files you're trying to import, and ChrisNZ's code could probably be modified without much difficulty to take in most of the edge cases, but personally I think solving this a different way would be preferable.  Just my $0.02.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

The simplest method - and bearing in mind you need to evaluate multiple assignments and such like for instance in one file abc might be c:\dir1, in another program it might be c:\dir2, so an automatic approach might not work - would be to take a copy of SASHELP.VLIBNAME, run the programs i.e. %include, then just take a list of SASHELP.VLIBNAME not in your copy:

E.g:

data temp;
  set sashelp.vlibnam;
run;

libname abc "s:\temp\rob";

proc sql;
  create table WANT as
  select * from SASHELP.VLIBNAM 
  except select * from TEMP;
quit; 

libname abc clear;

This will create want with one row for the libname I just created with name and path.  Far simpler than re-implementing a text parser to  work out what is what - note it wont pick up on duplicates however!

Peter_C
Rhodochrosite | Level 12
To generate code without the block-commented code, would this approach work?
Before the first line of the code add this statement:
%MACRO COMMENTREMOVAL ;
After all the statements, add statements
%MEND COMMENTREMOVAL ;
FILENAME MPRINT TEMP ;
OPTION MPRINT MFILE LRECL= 3000 ;
%COMMENTREMOVAL ;
RUN ;
OPTION NOMFILE ;
DATA _NULL_ ;
INFILE MPRINT ;
INPUT ;
LIST ;
RUN ;
I think this should echo to the log, a file of the code generated. It will not include the block-commented code. It has the downside that the code would need to be executed to generate this file of "clean" code.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 12 replies
  • 3324 views
  • 5 likes
  • 5 in conversation