我已将包含文件的目录读入数组。现在的问题是我想打开文件并在它们之间用一行显示它们的内容。
例如,我想打开file1.txt和file2.txt,并显示如下内容:
很高兴见到你 - 文件1
你好吗? - 文件2代码是:
sub openFile{
opendir(fol, "folder/details");
my @files= readdir(fol);
my @FilesSorted = sort(@files);
foreach my $EachFile (@FilesSorted) {
print $EachFile . "\n";
}
}
答案 0 :(得分:2)
如果你只想显示文件中的所有行(正如你的代码似乎试图做的那样),而没有任何关于哪个行来自哪个文件的指示,那么就有一个涉及预定义变量的技巧@ARGV
:
sub openFile {
opendir(fol, "folder/details");
@ARGV = sort(readdir(fol));
close fol;
while (<>) {
print "$_\n";
}
}
如果您需要打印文件名,则必须明确打开每个文件:
sub openFile {
opendir(fol, "folder/details");
my @files = sort(readdir(fol));
close fol;
while ($file = shift @files) {
open(FILE, $file);
while (<FILE>) {
print "$_\n";
}
close FILE;
}
}
答案 1 :(得分:2)
另一个例子,有一些错误检查和跳过子目录:
sub print_all_files {
my $dir = shift;
opendir(my $dh, $dir) || die "Can't read [$dir]: $!";
while(defined(my $file = readdir $dh)) {
next unless -f "$dir/$file"; # Ignore subdirs and . and ..
open(my $fh, "<", "$dir/$file") || die "Can't read [$dir/$file]: $!";
print while readline($fh);
print "\n"; # add an extra line
}
}
print_all_files("folder/details");
答案 2 :(得分:1)
尝试
sub openFile{
opendir(fol, "folder/details");
my @files= readdir(fol);
my @FilesSorted = sort(@files);
foreach my $EachFile (@FilesSorted) {
if($EachFile ne "." && $EachFile ne ".." && !(-d $EachFile)) { #important to skip the directories
open IT $EachFile || die "unable to read ".$EachFile."\n"; # open file
while($line = <IT>) { # print content in file
print "$line\n";
}
close(IT); # close file
print "-->$EachFile\n"; # print file name
}
}
答案 3 :(得分:1)
您可以使用File::Util之类的模块简化目录读取代码。它或类似的其他模块将提供一些便利:错误检查;过滤掉不需要的目录内容(如.
和..
子目录);按类型选择内容(例如,只是文件或目录);并将根路径附加到内容。
use strict;
use warnings;
use File::Util qw();
my $dir = 'folder/details';
my $file_util = File::Util->new;
my @files = $file_util->list_dir($dir, qw(--with-paths --no-fsdots --files-only));
for my $f (@files){
local @ARGV = ($f);
print while <>;
print "\n";
}
如果您不想使用其他模块,可以获取如下文件名:
opendir(my $dh, $dir) or die $!;
my @files = grep -f, map("$dir/$_", readdir $dh);
答案 4 :(得分:1)
这可以是一个独立的计划吗?
#! /usr/bin/env perl
use strict;
use warnings;
die "$0: no arguments allowed\n" if @ARGV;
my $dir = "folder/details";
opendir my $dh, $dir or die "$0: opendir $dir: $!";
while (defined(my $file = readdir $dh)) {
my $path = $dir . "/" . $file;
push @ARGV, $path if -f $path;
}
@ARGV = sort @ARGV;
while (<>) {
print;
}
continue {
print "\n" if eof && @ARGV;
}
备注强>
defined
检查从readdir
返回的每个值是必要的,以处理Perl中名称为false值的文件,例如,0
。 folder/details
中写入文件的内容,因此还需要使用-f
测试过滤普通文件。while (<>) { ... }
中的内置处理将参数从@ARGV
的前面移开。 eof
- 没有括号!{continue
子句中的-test检测每个文件的结尾,并将换行符打印为文件之间的分隔符,而不是终结符。答案 5 :(得分:0)
跟进Greg Bacon's回答(重新:“这可以是一个独立的程序吗?”),如果你仍然想在openFile
子程序中使用它,你可以在那里使用相同的循环:< / p>
sub openFile{
opendir(fol, "folder/details");
my @files= readdir(fol);
my @FilesSorted = sort(@files);
local @ARGV = @FilesSorted;
while (<>) {
print;
}
continue {
print "\n" if eof && @ARGV;
}
}
注意local @ARGV
的使用(如FMc's answer中所示):这将保留子例程外部的任何全局参数列表,并在退出时恢复该值。