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

Hi,

 

I want to Process a file If footer is present..

 

We need to process a file like below.. but with many variables

 

XXXX|TTTTT|HJJHJJK|909090

XXXX|TTTTT|HJJHJJK|909090

yyyyk|hdhbhhjpo|jhvjhvj|567884

yyyyk|hdhbhhjpo|jhvjhvj|567884

Total Number Of Recs:4

 

 

 

Please check the code:

 

%macro a;
 
data _null_;
infile "&Dfile" firstobs=1 end=eof
dsd missover lrecl=3000;
length input_rec $1024;
input input_rec $;
if eof then 
call symputx('footer', input_rec);
run;
%put &footer;
%let substring=Total number;
%let match =%index(%upcase(&footer),%upcase(&substring));
%if &match %then
%put Footer Exists;
%else 
%put Footer does not Exist;
 
%mend;
%a

 

Here The footer can be anything like TTL NO REC:4

So I should not be hardcoding the footer sub string..

 

Is there any Other Approach?

 

Edit by KurtBremser: moved the code from attachment to code window

It's not necessary to use an attached file for codes of considerably short length; use the proper sub-windows for that ("little running man", {i})

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

You can do it without macro coding in data steps:

%let match=0;
%let dlm=|;

data _null_;
infile "&Dfile." firstobs=1 end=eof dsd missover lrecl=3000 dlm="&dlm.";
input
  var1
  var2
  var3
  var4
;
if eof then do;
  if indexc(_infile_,"&dlm.") = 0 then call symput('match','1');
end;
run;

data _null_;
if &match
then put 'Footer present';
else put 'No footer present';
run;

Note that the code uses the presence of the delimiter to recognize a possoble footer line.

 

If you want to avoid reading the whole file, you could use a commandline tool to retrieve the last line:

filename oscmd pipe "tail -1 &Dfile.";

data _null_;
infile oscmd;
input;
if indexc(_infile_,"&dlm.") > 0
then call symput('match','0');
else call symput('match','1');
run;

(for UNIX systems)

View solution in original post

5 REPLIES 5
LinusH
Tourmaline | Level 20
Like with all situations when solving problems with programming you need to come up with a rule, that could be string matching, absence of a delimiter or something else.
Data never sleeps
Kurt_Bremser
Super User

You can do it without macro coding in data steps:

%let match=0;
%let dlm=|;

data _null_;
infile "&Dfile." firstobs=1 end=eof dsd missover lrecl=3000 dlm="&dlm.";
input
  var1
  var2
  var3
  var4
;
if eof then do;
  if indexc(_infile_,"&dlm.") = 0 then call symput('match','1');
end;
run;

data _null_;
if &match
then put 'Footer present';
else put 'No footer present';
run;

Note that the code uses the presence of the delimiter to recognize a possoble footer line.

 

If you want to avoid reading the whole file, you could use a commandline tool to retrieve the last line:

filename oscmd pipe "tail -1 &Dfile.";

data _null_;
infile oscmd;
input;
if indexc(_infile_,"&dlm.") > 0
then call symput('match','0');
else call symput('match','1');
run;

(for UNIX systems)

RW9
Diamond | Level 26 RW9
Diamond | Level 26

I agree with @Kurt_Bremser.  One thing I would also add is with regards to the file format.  What you have there is a delimited file, so the question is why does it have record count at the end?  Record count and other metadata should be part of the documentation associated with the transfer sure, but this should not be in the datafile, as what you have now is a corrupted delimited file.  Send it back and tell them to do it properly.

Astounding
PROC Star

You have an excellent suggestion from @Kurt_Bremser about how to read just the last observation from your file, instead of reading through all of them.  However, in case your file is short and you don't care about reading a few extra records, here is how you would work with your existing program to simplify it.

 

Keep it all in your DATA step.  It's easy to modify the end of your DATA step in this way.  First, move this statement to before the DATA step:

 

%let substring=Total number;

 

Then change the end of the DATA step:

 

if eof;

if index( upcase(input_rec), upcase("&substring") ) then put 'Footer Exists';

else put 'Footer does not Exist';

 

Everything else that follows the DATA step can disappear.

sfffdg
Obsidian | Level 7
Thank you sir for an elegant solution!!

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
  • 5 replies
  • 721 views
  • 3 likes
  • 5 in conversation