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
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.