2010-08-13 3 views
0

этим утром мы с моим другом обсудили и написали код ниже. Идея этого скрипта 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 с вышеупомянутым содержанием.

Спасибо заранее,

Vijay


Привет всем,
Я только изменил мой код. Пожалуйста, обратитесь к приведенному ниже разделу кода.

#!/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;  
}  

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

+2

Почему бы не использовать 'cp -r'? –

+0

Можете вы добавить свой материал? – jkramer

+3

Прочитайте одну или две книги о языке, который вы используете, и, возможно, программировании в целом. Шутки в сторону. В вашем скрипте нет строки, которая написана правильно. Прошу прощения, если этот комментарий причиняет вам боль, но здесь вам нужно улучшить. – msw

ответ

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?

+0

Да, вы правы, FM. На самом деле, я должен повторить new.txt. Поскольку у него есть структура каталогов, которая должна быть создана. Теперь я совершенно смущен. Не могли бы вы сделать это более понятным для меня? Мои вопросы: в файле new.txt есть структура каталогов, которая должна быть создана. Тогда, зачем я повторяю файл1? – Invincible

0

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

HOWEVER, методы, которые вы используете для выполнения своей работы, не совсем точны. Было бы лучше на самом деле использовать File::Path и File::Copy, и, в частности, ваш путь разделения пути в каталог и имя файла при первой косой черте - это ничего, кроме общего. Такие вещи нужно делать в библиотеках, из которых у Perl много.

+0

Изобразительное. Что я должен сделать, чтобы сценарий скопировал файлы в соответствующие каталоги? Не могли бы вы быть конкретными? Я пробовал с Shell Scripting, и он работает. Я не понимаю, почему тот же самый логин не работает с Perl! – Invincible

0

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

$line = <MYFILE>; 
chomp($line); 
Смежные вопросы