1

真的不确定我是否以正确的方式进行此操作。我正在尝试使用其中的第 7 行重命名文件(这是包含标题的标题信息)。这些文件是通过命令行参数放置的;所以 ./perl.pl file1 file2 等。我尝试做的是获取第一个 argv 并将其分配给数组 @file1 并获取第 7 个元素并使用它来重命名,但老实说我完全迷失了。任何人都可以告诉我如何做到这一点,无论是这种方式还是另一种方式。我正在尝试的代码是:

 #!/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 个。多谢你们

4

2 回答 2

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 $!;

}
于 2013-11-08T11:32:27.967 回答
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;
}
于 2013-11-08T12:37:36.437 回答