Path: utzoo!attcan!uunet!bu.edu!snorkelwacker!bloom-beacon!eru!hagbard!sunic!kth.se!news From: juha@ttds.tds.kth.se (Juha Sarlin) Newsgroups: comp.lang.perl Subject: a more find-like version of dodir Message-ID: Date: 12 Sep 90 21:06:44 GMT References: <1990Sep10.230742.9600@indetech.com> <9454@jpl-devvax.JPL.NASA.GOV> Sender: news@kth.se (News Administrator) Organization: /mnt/alla/juha/.organization Lines: 65 In-reply-to: lwall@jpl-devvax.JPL.NASA.GOV's message of 11 Sep 90 01:33:37 GMT Larry Wall's dodir doesn't work exactly like the unix-command find: - You always have to start in '.' and cannot give a list of files; this could be fixed with something like: chop($cwd = `pwd`); grep(chdir $_ && (&dodir($_), chdir $cwd), @files); - It always skips the starting directory. Eg, &dodir('.') doesn't print '.'. Here is dofiles, a modified version of dodir that fixes these problems and also makes errors in chdir and opendir non-fatal: #!/usr/local/bin/perl # Recursive directory walker. # Prints all pathnames given on the command line. If any of them # are directories their contents are printed recursively. # This is like: find ${*-.} -print unshift(@ARGV, '.') if $#ARGV < $[; &dofiles('', 0, @ARGV); sub dofiles { local($dir,$nlink,@filenames) = @_; local($dev,$ino,$mode); if ($nlink == 2) { # this dir has no subdirectories for (@filenames) { $name = $dir.$_; print $name,"\n"; } } else { # this dir has subdirectories local($back) = '..'; chop($back = `pwd`) unless $nlink; # first time for (@filenames) { $name = $dir.$_; print $name,"\n"; if (($dev,$ino,$mode,$nlink) = lstat($_)) { next unless -d _; if (chdir $_) { if (opendir(DIR,'.')) { (readdir(DIR) =~ /^\.$/ && readdir(DIR) =~ /^\.\.$/) || die "Directory $name doesn't start with . and .."; $name .= '/' unless /\/$/; &dofiles($name, $nlink, readdir(DIR)); } else { print STDERR "Can't open $name: $!\n"; } chdir $back; } else { print STDERR "Can't cd to $name: $!\n"; } } else { print STDERR "$name: $!\n"; } } } } -- Juha Sarlin juha@tds.kth.se