简体   繁体   中英

How to copy all the files of a particular type using Perl?

Right now, I am using something like

copy catfile($PATH1, "instructions.txt"), catfile($ENV{'DIRWORK'});

individually for each of the .txt files that I want to copy. This code is portable as it does not use any OS specific commands.

How can I copy all the text files from $PATH1 to DIRWORK , when I do not know the individual names of all the files, while keeping the code portable?

You can use the core File::Copy module like this:

use File::Copy;
my @files = glob("$PATH1/*.txt");

for my $file (@files) {
    copy($file, $ENV{DIRWORK}) or die "Copy failed: $!";
}

Using core File::Find and File::Copy and assuming you want all .txt files in $PATH1 copied to $ENV{DIRWORK} , and also assuming you want it to recurse...

use strict;
use warnings;
use File::Find;
use File::Copy;

die "ENV variable DIRWORK isn't set\n"
    unless defined $ENV{DIRWORK} and length $ENV{DIRWORK};
die "DIRWORK $ENV{DIRWORK} is not a directory\n"
    unless -d $ENV{DIRWORK};

my $PATH1 = q{/path/to/wherever};
die "PATH1 is not a directory" unless -d $PATH1;

find( sub{
    # $_ is just the filename, "test.txt"
    # $File::Find::name is the full "/path/to/the/file/test.txt".
    return if $_ !~ /\.txt$/i;
    my $dest = "$ENV{DIRWORK}/$_";
    copy( $File::Find::name, $dest ) or do {
        warn "Could not copy $File::Find::name, skipping\n";
        return;
    }
}, $PATH1 );

Give it a go ;)

Alternatively, why don't you use bash ?

$ ( find $PATH1 -type f -name '*.txt' | xargs -I{} cp {} $DIRWORK );

File::Find and File::Copy are portable:

use File::Find;
use File::Copy;

find(
    sub {
        return unless ( -f $_ );
        $_ =~ /\.txt$/ && copy( $File::Find::name, $ENV{'DIRWORK'} );
    },
    $PATH1
);

If you are guaranteed to work on a Unix system (eg don't care about portability), I'll go against my own usual inclinations and accepted best practices and recommend considering using "cp" :)

system("cp $PATH1/*.txt $ENV{'DIRWORK'}"); 
# Add error checking and STDERR redirection!

For Perl native solution, combine globbed file list (or File::Find) with File::Spec ability to find actual file name

my @files = glob("$PATH1/*.txt");
foreach my $file (@files) {
    my ($volume,$directories,$filename) = File::Spec->splitpath( $file );
    copy($file, File::Spec->catfile( $ENV{'DIRWORK'}, $filename ) || die "$!";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM