Path: utzoo!attcan!uunet!ogicse!dali!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!wuarchive!udel!princeton!phoenix!cucumber!viktor From: viktor@cucumber.Princeton.EDU (Viktor Dukhovni) Newsgroups: comp.lang.perl Subject: Re: How about building in directory-tree-walking? like "ftw()" Message-ID: <14767@phoenix.Princeton.EDU> Date: 23 Mar 90 06:34:52 GMT References: <39362@iuvax.cs.indiana.edu> <7514@jpl-devvax.JPL.NASA.GOV> Sender: news@phoenix.Princeton.EDU Distribution: comp Lines: 89 lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: >On the other hand, you can just mutate the following into what you want. >This actually runs faster than find on my system, but that's because it's >only looking at the names in leaf directories, not the inode. It also >assumes that directory link counts work in the standard fashion. How did you know I was writing a fast tree symbolic copy? :-) With a modified version of dodir, it got even faster, Thanks. And by the way here is a program that when duplicating large trees does a lot of mkdirs! Though forking once for 100 directories seems not too expensive. --------------------------------------- #! /usr/bin/perl ( $#ARGV != 1 ) && die "Usage: $0 \n" ; ($tail=$src=shift) !~ m,^/, && die "Use full src path name\n" ; ($dst=shift) !~ m,^/, && die "Use full dst path name\n" ; $tail =~ s,.*/,, ; $dst .= "/$tail" if ( -d $dst && ! ($dst =~ m,/$tail$,) ); if ( ! -d "$dst" ) { system "mkdir",$dst ; die "\n" if $? ; } chdir($src) || die "Could not chdir to $src\n" ; $np = $nd = 0 ; &dodir("",0); chdir($dst) || die "Could not chdir to $dst\n" ; while( $#dirs >= $[ ) { system("mkdir",splice(@dirs,-100,100)) ; die "\n" if $?; } for(@pathnames) { symlink($src."/".$_,$_) || die "$_: symlink failed\n"; } ;; ;; ;; sub dodir { local($dir,$nlink) = @_; local($dev,$ino,$mode); ($dev,$ino,$mode,$nlink) = stat('.') unless $nlink; # first time opendir(DIR,'.') || die "Can't open $dir"; local(@filenames) = readdir(DIR); closedir(DIR); if ($nlink == 2) { # this dir has no subdirectories for(@filenames) { $pathnames[$np++] = "$dir$_" if ( $_ ne '.' && $_ ne '..' ); } } else { # this dir has subdirectories for (@filenames) { next if $_ eq '.'; next if $_ eq '..'; $name = "$dir$_"; ($dev,$ino,$mode,$nlink) = stat($_); if (($mode & 0170000) != 0040000) { $pathnames[$np++] = $name ; next; } $dirs[$nd++] = $name ; chdir $_ || die "Can't cd to $name"; &dodir($name."/",$nlink); chdir '..'; } } } Viktor Dukhovni : ARPA <...!uunet!princeton!math!viktor> : UUCP Fine Hall, Washington Rd., Princeton, NJ 08544 : US-Post +1-(609)-258-5792 : VOICE