in reply to To retrieve all files according to given path list

What have you tried and failed at? Let's see some code please!

There is more ways of doing what you are asking than there are programmers programming in Perl. One suggestion I would give you is to run the "find2perl" command with a minimum of arguments to produce a file you can hack on.

For instance if I run the command

find2perl somedir -depth -type f > somefile.pl
I will get the starts of a program in the file somefile.pl with the following contents:
#! /usr/bin/perl -w eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if 0; #$running_under_some_shell use strict; use File::Find (); # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; sub wanted; # Traverse desired filesystems File::Find::finddepth({wanted => \&wanted}, 'somedir'); exit; sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && -f _; }
Now an enterprising programmer can edit that file to give it any behaviors that they want, and to boot it is a good way to learn how to use the File::Find module and friends.

Now, if you wanted to re-invent the wheel you could also write something that was a combination of calls to opendir and friends with some glob calls to handle wildcards and things like that.

I hope this nudges you on to the path of Perl Rightousness...


Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

Replies are listed 'Best First'.
Re^2: To retrieve all files according to given path list
by devlele (Novice) on Dec 22, 2005 at 16:43 UTC


    I have tried following code, where I am assigning @ARGV[0] to $directory variable and then passing $directory variable to sub wanted as you can see in the following code. But it only accepts "C:\directoryname" as an argument. I want the code to handle all the cases such as "C:\", "C:\*", C:\direcoryname\*" etc as I showed in my original email. Also is there any way to handle multiple paths or pathlist provided on command line ?

    Please help.

    Thanks
    find(\&wanted, $directory); sub wanted { if (-d $_) { $totaldirs++; return; } else { $totalfiles++; @Stats = stat($_); $size = $Stats[7]; $ATime = $Stats[8]; $ModTime = $Stats[9]; $CTime = $Stats[10]; if (!$Windows && $opt_o ) { $owner = $Stats[4]; $owner = "\\" . getpwuid($owner); if ($owner eq "\\") { $owner = ''; } } elsif ($hasWin32Perms && $opt_o) { $object = new Win32::Perms ( $_ ) || die; $owner = $object->Owner(); $object->Close(); } ################################################################## +################ ## Filter Checks # Owner if ($i_owners && ($i_owners ne $owner) && $opt_o) { return; } # File Size if ($i_filesizemax && $i_filesizemin) { if ($size > $i_filesizemax || $size < $i_filesizemin) { next; +} } # Included File Types if (@i_incfiletypes) { $match = 0; foreach my $ext (@i_incfiletypes) { $ext =~ s/^\.//; if ($_ =~ m/.$ext$/) { $match = 1; last; } } if (!$match) { return; } } # Excluded File Types if (@i_excfiletypes) { $match = 0; foreach my $ext (@i_excfiletypes) { $ext =~ s/^\.//; if ($_ =~ m/.$ext$/) { $match = 1; last; } } if ($match) { return; } } # Date Modified if ($i_datemodifiedstart && $i_datemodifiedend) { if ($ModTime < $i_datemodifiedstart || $ModTime > $i_datemodif +iedend) { next; } } # Date Created if ($i_datecreatedstart && $i_datecreatedend) { if ($CTime < $i_datecreatedstart || $CTime > $i_datecreatedend +) { next; } } # Date Accessed if ($i_dateaccessedstart && $i_dateaccessedend) { if ($ATime < $i_dateaccessedstart || $ATime > $i_dateaccessede +nd) { next; } } $filterfiles++; ################################################################## +################ $writer->startTag("File"); ## OWNER ### $writer->dataElement("FileOwner", $owner);All files in directoryna +me and its subdirectories. $dir = $File::Find::dir; #$dir =~ s!\/!!; $dir =~ s!/!\\!g; $dir =~ s!\\\\!\\!; $dir = $dir . "\\"; $dir =~ s!:\\\\!:\\!; $writer->dataElement("FilePath", $dir); $writer->dataElement("FileName", $_); ################################################################## +################ ## FILE ACCESSED ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( +$ATime); $year += 1900; $mon++; $mday = "0$mday" if $mday < 10; if ($hour > 12) { $hour = $hour - 12; $ampm = "PM"; } else { $hour = 12 if $hour == 0; $ampm ="AM"; } $min = "0$min" if $min < 10; $sec = "0$sec" if $sec < 10; #print "\t\t<FileAccessed>$mon/$mday/$year $hour:$min:$sec $ampm< +/FileAccessed>\n"; #$writer->dataElement("FileAccessed", "$mon/$mday/$year $hour:$min +:$sec $ampm"); $writer->dataElement("FileAccessed", "$mon/$mday/$year"); ################################################################## +################ ## FILE MODIFIED ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( +$ModTime); $year += 1900; $mon++; $mday = "0$mday" if $mday < 10; if ($hour > 12) { $hour = $hour - 12; $ampm = "PM"; } else { $hour = 12 if $hour == 0; $ampm ="AM"; } $min = "0$min" if $min < 10; $sec = "0$sec" if $sec < 10; #print FH "\t\t<FileModified>$mon/$mday/$year $hour:$min:$sec $amp +m</FileModified>\n"; #$writer->dataElement("FileModified", "$mon/$mday/$year $hour:$min +:$sec $ampm"); $writer->dataElement("FileModified", "$mon/$mday/$year"); ################################################################## +################ ## FILE CREATED ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime( +$CTime); $year += 1900; $mon++; $mday = "0$mday" if $mday < 10; if ($hour > 12) { $hour = $hour - 12; $ampm = "PM"; } else { $hour = 12 if $hour == 0; $ampm ="AM"; } $min = "0$min" if $min < 10; $sec = "0$sec" if $sec < 10; #$writer->dataElement("FileCreated", "$mon/$mday/$year $hour:$min: +$sec $ampm"); $writer->dataElement("FileCreated", "$mon/$mday/$year"); ################################################################## +################ # Turn size into KB and round up to next integer divisible by 4 $size = ceil($size / 1024); while ($size % 4 != 0) { $size++; } $writer->dataElement("FileSize", $size); $writer->endTag(); } } $writer->endTag(); $writer->end(); $output->close(); ##################################################################### print "File Scan is complete.\n"; print ":::Statistics:::\nDirectories:\t$totaldirs\nFiles:\t$totalfiles +\nFiles that passed Filters:\t$filterfiles\n";
          I want the code to handle all the cases such as "C:\", "C:\*", C:\direcoryname\*" etc as I showed in my original email.

      For that you are going to have to write logic to expand out your wild cards. For instance take a look at glob. There are other ways, but that's a start.


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      I have tried following code, where I am assigning @ARGV[0] to $directory variable and then passing $directory variable to sub wanted as you can see in the following code. But it only accepts "C:\directoryname" as an argument. I want the code to handle all the cases such as "C:\", "C:\*", C:\direcoryname\*" etc as I showed in my original email. Also is there any way to handle multiple paths or pathlist provided on command line ?

      When I'm under windows I often do

      BEGIN { @ARGV = map glob, @ARGV }

      And indeed to File::Find's find() you can pass more than one directory to search. From perldoc File::Find:

      SYNOPSIS use File::Find; find(\&wanted, @directories_to_search); sub wanted { ... } use File::Find; finddepth(\&wanted, @directories_to_search); sub wanted { ... }