Hello,
I am using the following macro to get the owner and group and individually, it works well.
%macro ReadOwnerNGroup(pathNfileName);
data _null_;
infile "ls -l '&pathNfileName.'" pipe;
input perms :$20. links owner :$20. group :$20.;
call symputx("owner",owner,'G');
call symputx("group",group,'G');
run;
%mend ReadOwnerNGroup;
Then I provide a dataset containing three different path and filename like below:
/*the real info about path and filename are replaced for safety purpose*/
DATA Info;
length PathNFileName $ 150;
INFILE DATALINES ;
INPUT PathNFileName & $ ;
DATALINES;
/path1/filename1
/path1/filename2
/path1/filename3
/path2/filename4
/path3/filename5
;
run;
Then I calculate the number of obs;
proc sql noprint;
%global nobs;
select count(*) into: nobs
from info;
quit;
%put &nobs;
Then I am trying to gather all the information but I think I always getting the owner and the group of the last records.
Is there a way to solve that issue.
Data info2;
do Slice=1 to &nobs.;
set info point=Slice;
call execute('%nrstr(%ReadOwnerNGroup('!!(pathNfileName)!!'));');
Owner=symget('owner');
Group=symget('group');
output;
end;
stop;
run;
Use a "dynamic pipe":
DATA Info;
length PathNFileName $ 150;
INFILE DATALINES ;
INPUT PathNFileName & $ ;
DATALINES;
/path1/filename1
/path1/filename2
/path1/filename3
/path2/filename4
/path3/filename5
;
data ownership;
set info;
length fvar $200;
fvar = 'ls -l ' !! PathNFileName;
infile dummy pipe filevar=fvar;
input perms :$20. links owner :$20. group :$20.;
run;
But for this particular issue, you may be better off using the built-in file functions.
You've got a timing issue. call execute() gets stacked and only executes once your data step iterated through all the rows. Using the dosubl() function instead should get you around this issue.
An alternative and likely easier way would be to use the filename() function together with the finifo() function. The docu for finfo() provides a link to an example which is already very close to what you're trying to achieve.
Use a "dynamic pipe":
DATA Info;
length PathNFileName $ 150;
INFILE DATALINES ;
INPUT PathNFileName & $ ;
DATALINES;
/path1/filename1
/path1/filename2
/path1/filename3
/path2/filename4
/path3/filename5
;
data ownership;
set info;
length fvar $200;
fvar = 'ls -l ' !! PathNFileName;
infile dummy pipe filevar=fvar;
input perms :$20. links owner :$20. group :$20.;
run;
But for this particular issue, you may be better off using the built-in file functions.
Expand the assignment of the fvar variable:
fvar = 'ls -l ' !! quote(strip(PathNFileName),"'");
And there's a reason for Maxim 44. Those blanks serve no purpose that can't be solved with underlines and only cause extra work.
No need to use macro code. Also if any of those filenames are directories your code will blow up. Include -d option to the ls command.
data Info;
infile datalines truncover ;
input PathNFileName $256. ;
DATALINES;
/path1/filename1
/path1/file name 2
/path1/filename3
/path2/filename4
/path3/filename5
;
data info2;
set info;
length cmd $300;
cmd = catx(' ','ls -ld',quote(trim(pathnfilename)));
infile cmd pipe filevar=cmd truncover ;
input perms :$20. links owner :$20. group :$20.;
run;
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
Check out this tutorial series to learn how to build your own steps in SAS Studio.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.