Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

writtings files to a new folder

by heidi (Sexton)
on Jan 24, 2007 at 05:41 UTC ( [id://596203]=perlquestion: print w/replies, xml ) Need Help??

heidi has asked for the wisdom of the Perl Monks concerning the following question:

Am a beginner in perl, i have a list of names of text files('one.txt','two.txt','three.txt') in an array called @files. these files and its contents along with other text files are already in a folder called "old". i want to check whether the file names which i have in the array @files are present in the "old" folder, and if present, i have to copy those files to a newfolder called "new". i have no idea how to do this.

Replies are listed 'Best First'.
Re: writtings files to a new folder
by gaal (Parson) on Jan 24, 2007 at 06:05 UTC
    To move a file, use the File::Copy module, but make sure the move worked by looking at the return value. To check if a file exists somewhere, use the -f FILENAME builtin. To go over all the files, use for. Putting it all together:

    use File::Copy; our $VERBOSE = 1; # turn this off if you don't need the verbose messag +es for my $file (@files) { if (-f "old/$file") { print "old/$file -> new/$file\n" if $VERBOSE; move("old/$file", "new/.") or die "move: old/$file: $!"; } }

    Note that if this encounters an error, it'll stop in the middle. Maybe in your application it's more right to push the erring filename to a @failed array and then print them all, retry, whatever. I don't know; it's just something to think about.

    Also, I've assumed "/" is a correct filepath separator and in most cases it is, but if you want to write really portable code you'll want to look into File::Spec.

      Also, I've assumed "/" is a correct filepath separator and in most cases it is, but if you want to write really portable code you'll want to look into File::Spec.

      That's not the complete picture, as non-Unix operating systems support POSIX syntax (i.e. Unix) besides their own native syntax. All operating systems that run perl support POSIX syntax, otherwise the perl build process wouldn't work. For a bizarre native syntax, have a look at VMS. There can be problems if you try and mix native and POSIX, though sometimes in Windows, you can get away with a mixture of slashes leaning both ways.

      My advice is to either stick to native syntax, with File::Spec and friends, or use POSIX syntax throughout. Beware that a user supplied filename might contain native syntax elements.

      For more on this, and portability in general, please refer to my talk slides - I have given this talk at several YAPCs.

      --

      Oh Lord, won’t you burn me a Knoppix CD ?
      My friends all rate Windows, I must disagree.
      Your powers of persuasion will set them all free,
      So oh Lord, won’t you burn me a Knoppix CD ?
      (Missquoting Janis Joplin)

Re: writtings files to a new folder
by siva kumar (Pilgrim) on Jan 24, 2007 at 09:12 UTC
    Hope below code may help you.
    Create the directory 'new' before running the script.
    #!/usr/bin/perl use strict; use File::Copy; my @files = ('one.txt','two.txt','three.txt'); for my $file (@files) { if (-f "old/$file") { print "old/$file moved to new/$file\n" ; copy("old/$file", "new/.") or die "Error Coping /old/$file: $! +"; } }
Re: writtings files to a new folder
by MaxKlokan (Monk) on Jan 24, 2007 at 09:40 UTC
    For a beginner my solution is perhaps too cryptic, but I am going to give it anyway, just in case somebody finds it interesting.
    You can do it all with a single command if you use grep, which can be used to apply a block of statements to all elements in a list :
    use File::Copy; grep { (move("old/$_", "new/.") or warn "$_ => $!") if -f } @files;
    The default variable $_ is set to each element of the list and the operator -f can work with it.
    $! is the error message if an error has indeed occurred.
      If you're going to use dense loop constructs like this, 'map' is a slightly better choice than grep for expressing your intentions. Or probably even better:
      do { some; series of; commands; which can use $_; } foreach @files;
      But this is only if you have an aversion to newlines (which I can relate to), since this clearly the same as:
      foreach (@files) { some; series of; commands; which can use $_; }
        Thinking of it, I myself would probably use do {...} foreach @list; as you suggest, because I find it more readable.
        At first I found that particular use of grep intriguing. Then again, I wonder whether it was a good idea to add such a (potentially confusing) functionality to grep, since foreach works perfectly fine.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://596203]
Approved by chargrill
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-25 07:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found