Почему этой программе не удается скопировать файлы? - PullRequest
0 голосов
/ 13 августа 2010

сегодня утром мы с другом обсудили и написали следующий код. Идея этого сценария 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;
}

Приведенный выше фрагмент кода создает структуру каталогов, но не может скопировать файлы в соответствующий каталог. Не могли бы вы сообщить нам, где именно мы не правы?

Содержимое файла1:

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 ]

1 голос
/ 13 августа 2010

Ваша цель мне не ясна, но, возможно, это поможет вам решить проблему:

# 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?

0 голосов
/ 13 августа 2010

Бьюсь об заклад, ваша переменная $line по-прежнему имеет новую строку. Входные данные, возвращаемые оператором ввода дескриптора файла (<MYFILE>), включают разделитель записей (обычно это символы новой строки для вашей ОС). Попробуйте это:

$line = <MYFILE>;
chomp($line);
0 голосов
/ 13 августа 2010

Первое, что нужно сделать, если что-то «не работает», это отловить ошибки и посмотреть на них.Затем исследовать содержание переменных.В вашем случае переменная $to просто содержит имя файла, поэтому сценарий копирует его в текущий рабочий каталог, я полагаю, а не во вновь созданный каталог.методы, которые вы используете для выполнения своей работы, не совсем лучшие.Было бы лучше на самом деле использовать File::Path и File::Copy, и, в частности, ваш способ разбиения пути на каталог и имя файла в первом слэше совсем не общий.Такого рода вещи следует делать в библиотеках, которых в Perl много.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...