【问题标题】:Why does this program fail to copy files?为什么这个程序无法复制文件?
【发布时间】:2010-08-13 10:20:25
【问题描述】:

今天早上,我和我的朋友讨论并编写了以下代码。这个 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;    
}    

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

【问题讨论】:

  • 可以添加输出吗?
  • 阅读一两本书,了解您正在使用的语言以及可能的一般编程。严重地。您的脚本中没有一行是正确编写的。如果这条评论伤害了你的感情,我很抱歉,但这是你需要改进的地方。
  • 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 创建目录 test/test1/test2/将文件 /Vijay/new.txt 复制到 test/test1/test2/test.txt cp:不能访问/Vijay/new.txt:没有这样的文件或目录>目录'Vijay'有文件new.txt与上述内容。
  • @msv:很痛。但是,对于初学者和浪费了所有机会的人来说,值得这样做:(谢谢。
  • 当我开始重构这个程序时,我注意到它的编写方式是无可救药的。我不知道你是想对/Vijay/new.txt 的内容进行操作还是复制文件本身——就像现在一样,程序两者都没有。请edit the question 并简单地添加您要实现的算法的低级描述。

标签: perl copy


【解决方案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

【讨论】:

  • 是的,你是对的,FM。实际上,我应该迭代 new.txt。因为它有需要创建的目录结构。我现在完全糊涂了。你能让我更清楚一点吗?我的问题是,new.txt 文件具有需要创建的目录结构。那我为什么要迭代file1呢?
【解决方案2】:

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

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

【讨论】:

  • 很好。我应该怎么做才能使脚本将文件复制到相应的目录?你能具体点吗?我尝试使用 Shell Scripting,它确实有效。我不明白,为什么 Perl 不能使用同样的登录方式!
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多