2013-11-08 3 views
1

Действительно не уверен, что я собираюсь сделать это правильно или нет. Я пытаюсь переименовать файлы, используя 7-ю строки в них (которая является информацией заголовка, содержащей заголовок). Файлы передаются через командную строку args; поэтому ./perl.pl file1 file2 и т. д. То, что я пробовал делать, - это взять первый argv и назначить его массиву @ file1 и взять 7-й элемент и использовать его для переименования, но, честно говоря, я полностью потерян. Может кто-нибудь, пожалуйста, покажите мне, как я могу это сделать, так или иначе. Мой код, который я пытался это:Perl массивы в массивах?

#!/usr/bin/perl 

use strict; 
use warnings; 

my @file1 = $ARGV[0]; 
my @file2 = $ARGV[1]; 
my @file3 = $ARGV[2]; 
my @file4 = $ARGV[3]; 
my @file5 = $ARGV[4]; 

rename $ARGV[0], $file1[7]; 
rename $ARGV[1], $file2[7]; 
rename $ARGV[2], $file3[7]; 
rename $ARGV[3], $file4[7]; 
rename $ARGV[4], $file5[7]; 

Есть также, возможно, более гибкий способ принятия в аргументах, так что я не может быть больше, чем 5 файлов ввода. Спасибо, ребята

+0

было бы полезно, чтобы показать аргументы строки реальной команды и примеры, как файлы должны быть переименованы –

+0

Как и в ./perl. pl test1.txt test2.txt и сказать, что 7-й строки test1.txt - «Flying pigs», поэтому я хотел бы переименовать файл как Flying Pigs.txt – S3ekhmet

ответ

4

Вы можете перебрать @ARGV, которые являются параметрами командной строки, и переименовать каждый файл, возвращая значение get_line().

get_line() открывает $file для чтения и, когда на 7-й линии (if ($. == $n)), она удаляет символ новой строки (chomp $line) и возвращает содержание 7-й линии.

use strict; 
use warnings; 

sub get_line { 
    my ($file, $n) = @_; 

    open my $fh, "<", $file or die $!; 
    while (my $line = <$fh>) { 
    if ($. == $n) { chomp $line; return $line; } 
    } 
    return; 
} 

for my $file (@ARGV) { 
    rename ($file, get_line($file, 7)) or warn $!; 

} 
+0

Большое спасибо @mpapec. Было бы слишком много неприятностей для вас, чтобы сделать быструю английскую интерпретацию, потому что я не знаком с этим кодом, поэтому это было бы большой помощью в понимании. – S3ekhmet

+0

Мне нравится ваш answser лучше, удалил мой – Vorsprung

+0

Ahh в порядке, это имеет смысл. Спасибо :) – S3ekhmet

4

Perl имеет некоторые особенности командной строки, чтобы справиться с этим гладко:

perl -nlwe'if ($. == 7) { rename $ARGV, $_ or die $!; close ARGV; }' files* 

Это версия командной строки более длинного кода:

while (<>) { 
    chomp; 
    if ($. == 7) { 
     rename $ARGV, $_ or die $!; 
     close ARGV; 
    } 
} 

Это будет цикл по содержанию файлы в списке аргументов @ARGV. Когда дело доходит до строки 7, оно переименует файл, а затем перейдет к следующему файлу. Закрытие дескриптора файла приведет к пропуску следующего файла и сбросит счетчик строк $..

Как примечание на вашем алгоритме, возможно, было бы целесообразно, чтобы проверить, так что файлы не будут перезаписаны, такие как

if (! -e $_) { rename ... } else { warn "$_ already exists!" } 

Как mpapec говорит, что это может быть хорошей идеей, чтобы принять меры предосторожности против файлов с менее 7 строк, которые могут повредить вещи. Лучший способ сделать это в данном случае был бы проверить для преждевременного конца файла eof

if ($. == 7) { # the regular check 
    ... 
} elsif (eof) { 
    warn "File '$_' too short"; 
    close ARGV; 
} 
+1

отличный, возможно, реселлинг '$ .', если файл имеет менее 7 строк –

+0

Это хороший момент. – TLP

Смежные вопросы