LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (July 2007, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Fri, 20 Jul 2007 07:30:10 -0700
Reply-To:     chris@OVIEW.CO.UK
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         chris@OVIEW.CO.UK
Organization: http://groups.google.com
Subject:      Re: another recursion problem
Comments: To: sas-l@uga.edu
In-Reply-To:  <200707191554.l6JAkSIR027870@mailgw.cc.uga.edu>
Content-Type: text/plain; charset="us-ascii"

Hi Cary,

I'm not sure what was wrong with your original code - I couldn't run it as I don't have the %isdir utility macro available here. I've rewritten your code slightly as below, and this works as you'd expect:

%macro dirWalk(fname); /* Walk a directory structure recursively. */ /* For now simply list the contents of all */ /* subdirectories. */ %local i filrf rc did memcnt;

* Try to open this fname as a directory; %let rc=%sysfunc(filename(filrf,&fname)); %let did=%sysfunc(dopen(&filrf));

%if &did > 0 %then %do;

* seems to be a directory, so walk it;

%let memcnt=%sysfunc(dnum(&did));

%if &memcnt > 0 %then %do i=1 %to &memcnt; %let name=&fname/%sysfunc(dread(&did,&i)); %put &i &name; %dirWalk(&name); %end; %let rc=%sysfunc(dclose(&did));

%end;

%mend dirWalk;

%dirwalk(~/recurse);

1 ~/recurse/file1 2 ~/recurse/file2 3 ~/recurse/file3 4 ~/recurse/dir1 1 ~/recurse/dir1/dir11 1 ~/recurse/dir1/dir11/file1 2 ~/recurse/dir1/dir11/file2 3 ~/recurse/dir1/dir11/file3 2 ~/recurse/dir1/file1 3 ~/recurse/dir1/file2 5 ~/recurse/dir2 1 ~/recurse/dir2/file1 2 ~/recurse/dir2/file2

While it's interesting to learn about recursion, and SAS's file/ directory handling functions, by playing with this, I think that if you're doing any serious work that requires this sort of manipulation of the file system, you'd almost certainly be better off doing it in Perl rather than SAS.

Chris. -------------------------------------------------------- Elvis SAS Log Analyser - http://www.oview.co.uk/elvis Recover runnable SAS code from your log's MPRINT lines. --------------------------------------------------------

On 19 Jul, 16:54, cmill...@COQIO.SDPS.ORG (Cary Miller) wrote: > Thank you to all who responded to my post about the factorial > function. I agree with the comment about recursion not being > useful in practice. The only time I have found it useful is > for walking a directory tree. That is the problem I am currently > working on. The code and log below show the problem. > > %macro dirWalk(fname); > /* Walk a directory structure recursively. */ > /* For now simply list the contents of all */ > /* subdirectories. */ > %if %isDir(&fname) %then %do; *look at files; > %local filrf rc did memcnt; > /* The block below is lifted from SAS example 588 */ > %let filrf=mydir; > %let rc=%sysfunc(filename(filrf,&fname)); > %let did=%sysfunc(dopen > (&filrf)); > > %let memcnt=%sysfunc(dnum(&did)); > /* End of example 588 */ > %if &memcnt GT 0 %then *the dir has something in it; > %do i=1 %to &memcnt; *loop through all files > and...; > %let name=&fname\%sysfunc(dread(&did,&i)); > *get names; > %put &i &name; > %dirWalk(&name); *error:: does only the > FIRST subdir (incorrectly!); > * and then exits the > original macro call; > %end; > %put fname:&fname rc:&rc did:&did memcnt:&memcnt; > %let rc=%sysfunc(dclose(&did)); > %end; > %mend dirWalk; > %dirwalk(s:\foo2); > %dirwalk(s:\foo\a); > %dirwalk(s:\foo); > > 198 %dirwalk(s:\foo2); > 1 s:\foo2\f.txt > fname:s:\foo2 rc:0 did:1 memcnt:1 > > 199 %dirwalk(s:\foo\a); > 1 s:\foo\a\x.txt > 2 s:\foo\a\y.txt > fname:s:\foo\a rc:0 did:1 memcnt:2 > > 200 %dirwalk(s:\foo); > 1 s:\foo\c.txt > 2 s:\foo\d.sas > 3 s:\foo\a > 1 s:\foo\a\c.txt > 2 s:\foo\a\d.sas > 3 s:\foo\a\a > 4 s:\foo\a\b > fname:s:\foo\a rc:20036 did:2 memcnt:4 > fname:s:\foo rc:0 did:1 memcnt:4 > > The macro works for directories with no subdirs but > when it starts recursively looking at a subdir it continues > reading files from the parent. It looks like macro vars &rc > and &did are not getting the correct values in the recursive > call. I thought declaring the vars local would make this work > but no such luck. > > Directory foo contains subdirs a,b and files c.txt, d.sas. > Directory foo\a contains files x.txt and y.txt. > When the recursion gets to foo\a the names from foo get tacked > onto foo\a. > I'm stumped. Any ideas will be extremely welcome.


Back to: Top of message | Previous page | Main SAS-L page