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})
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)
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)
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.
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.
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.
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.
Ready to level-up your skills? Choose your own adventure.