很多问题。从调用“ls | grep”开始:)
让我们从一些代码开始:
首先,让我们获取文件列表:
my @files = glob( '*.txt' );
但最好测试给定名称是否与文件或目录相关:
my @files = grep { -f } glob( '*.txt' );
现在,让我们打开这些文件来阅读它们:
my @fhs = map { open my $fh, '<', $_; $fh } @files;
但是,我们需要一种处理错误的方法——在我看来,最好的方法是添加:
use autodie;
在脚本的开头(以及安装 autodie,如果你还没有的话)。或者,您可以:
use Fatal qw( open );
现在,我们有了它,让我们从所有输入中获取第一行(如您在示例中所示),并将其连接起来:
my $concatenated = '';
for my $fh ( @fhs ) {
my $line = <$fh>;
$concatenated .= $line;
}
这是非常好的,可读的,但仍然可以缩短,同时保持(在我看来)可读性,以:
my $concatenated = join '', map { scalar <$_> } @fhs;
效果是一样的 - $concatenated 包含所有文件的第一行。
所以,整个程序看起来像这样:
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
# use Fatal qw( open ); # uncomment if you don't have autodie
my @files = grep { -f } glob( '*.txt' );
my @fhs = map { open my $fh, '<', $_; $fh } @files;
my $concatenated = join '', map { scalar <$_> } @fhs;
现在,您可能不仅想连接第一行,还想连接所有行。在这种情况下$concatenated = ...
,您需要这样的东西,而不是代码:
my $concatenated = '';
while (my $fh = shift @fhs) {
my $line = <$fh>;
if ( defined $line ) {
push @fhs, $fh;
$concatenated .= $line;
} else {
close $fh;
}
}