为什么这个程序无法复制文件?

时间:2010-08-13 10:20:25

标签: perl copy

今天早上,我和我的朋友讨论并编写了以下代码。这个Perl脚本背后的想法是创建目录结构并将文件复制到相应的目录。

#!/usr/bin/perl
use File::Path;
use File::Copy;
use Path::Class;
use File::Basename qw/dirname/;
my $src = "/Vijay/new.txt";
unless (open(MYFILE, "file1")) {
    die ("cannot open input file file1\n");
}
$line = <MYFILE>;
while ($line ne "") {
    print ($line);
    mkdir_and_copy($src,$line);
    $line = <MYFILE>;
}
sub mkdir_and_copy {
    my ($from, $to) = @_;
    my($directory, $filename) = $to =~ m/(.*\/)(.*)$/;
    print("creating dir $directory");
    system "mkdir -p $directory";
    print("copying file $from to $to");
    system "cp -f $from $to";
    return;
}

上面的代码创建了目录结构,但无法将文件复制到相应的目录。能不能告诉我们,我们到底哪里错了?

file1的内容:

test/test1/test2/test.txt

new.txt的内容:

Shell/Test/test1/test1.txt
Shell/Test/test2/test2.txt
Shell/Test/test3/test3.txt

输出:

> ./mypgm.pl
test/test1/test2/test.txt
creating dir test/test1/test2/copying file /Vijay/new.txt to     test/test1/test2/test.txt
cp: cannot access /Vijay/new.txt: No such file or directory
>

目录Vijay的文件new.txt包含上述内容。

提前致谢,

维杰


大家好,
我只是修改了我的代码。请参阅以下代码部分。

#!/usr/bin/perl        
use File::Path;    
use File::Copy;    
use File::Basename qw/dirname/;    

my $src = "./Vijay/new.txt";       
unless (open(MYFILE, "file1"))    
{    
die ("cannot open input file file1\n");    
}

$line = ;
while ($line ne "")
{
print ($line); print("\n");
mkdir_and_copy($src,$line);
$line = ""; }

sub mkdir_and_copy        
{      
my ($from, $to) = @_;    
my($directory, $filename) = $to =~ m/(.\/)(.)$/;    
$temp = $directory.$filename;    
print("Creating dirrectory $directory \n");    
if(! -d $directory)    
{    
mkpath($directory) #or die "Failed to create path";    
}    
printf("From: $from \n");    
printf("To: $temp \n");    
copy($from,$temp) or die "Failed to Copy";    
return;    
}    

现在,它创建了确切的目录结构并将文件复制到相应的目录。能告诉我,上面的代码是否合适?

3 个答案:

答案 0 :(得分:1)

我的目标不明确,但也许这可以帮助您解决问题:

# Perl scripts should always include this.
# Your original script was generating some useful warnings.
use strict;
use warnings;

my $src = "/Vijay/new.txt";
my $f1  = 'file1';

# This is the recommended way to open a file --
# that is, using a lexical file handle.
open(my $file_handle, '<', $f1) or die "open() failed : $f1 : $!";

# This is the typical way of iterating over the lines in a file.
while (my $line = <$file_handle>){
    # You probably want to remove the newline
    # before passing the line to mkdir_and_copy()
    chomp $line;

    mkdir_and_copy($src, $line);
}

sub mkdir_and_copy {
    my ($from, $to) = @_;
    my ($directory, $filename) = $to =~ m/(.*\/)(.*)$/;

    # When writing a script that makes system() calls,
    # start by simply printing them. After everything
    # looks good, convert the print commands to system() calls.
    print "system(): mkdir -p $directory", "\n";
    print "system(): cp -f $from $to",     "\n";

    # The return is not needed.
}

当我使用您提供的输入运行脚本时,这是输出:

system(): mkdir -p test/test1/test2/
system(): cp -f /Vijay/new.txt test/test1/test2/test.txt

这不是你的意图。特别是,当它只包含一行时,为什么要迭代file1?也许你打算迭代new.txt

答案 1 :(得分:0)

如果“无法正常工作”,首先要做的就是捕捉错误并查看错误。然后调查变量的内容。在您的情况下,变量$to只包含文件名,因此脚本将其复制到当前工作目录中,我想,而不是新创建的目录。

HOWEVER ,您用来完成工作的方法并不是最好的方法。实际使用File::PathFile::Copy会更好,特别是在第一个斜杠处将路径拆分为目录和文件名的方式不是一般的。这种事情应该在库中完成,其中Perl有很多。

答案 2 :(得分:0)

我敢打赌你的$line变量仍然附加了换行符。从文件句柄输入操作符(<MYFILE>)返回的输入包括记录分隔符(通常是操作系统的换行符)。试试这个:

$line = <MYFILE>;
chomp($line);