如何修改这个 Perl 子例程,以便它使用 print_file 打印文件的内容?
Posted
技术标签:
【中文标题】如何修改这个 Perl 子例程,以便它使用 print_file 打印文件的内容?【英文标题】:How can I modify this Perl subroutine so that it prints the contents of the file, using print_file? 【发布时间】:2022-01-01 08:04:54 【问题描述】:阅读 Allen B. Downey 的 Learning Perl the Hard Way。
练习 1.1 说:
glob 运算符将模式作为参数并返回一个列表 匹配给定模式的所有文件。 glob 的一个常见用途是列出文件 在目录中。
my @files = glob "$dir/*";
$dir/*
模式表示“目录中名称存储在$dir
中的所有文件”。 有关其他模式的示例,请参阅 glob 的文档。 编写一个名为 print dir 的子程序,它将目录的名称作为参数 并打印该目录中的文件,每行一个。
我做到了:
#!/usr/bin/perl
sub print_dir
my $dir = shift;
my @files = glob "$dir/*";
foreach my $file (@files)
print "$file\n";
print_dir @ARGV;
然后练习 1.2 说“修改前面的子程序,而不是打印名称 文件,它使用 print_file 打印文件的内容。'
我正在努力解决这个问题。我有一个打印文件内容的脚本:
#!/usr/bin/perl
use strict;
use warnings;
sub print_file
my $file = shift;
open(my $FILE, $file)
or die $!;
while (my $line = <$FILE>)
print $line;
sub cat
foreach my $file (@_)
print_file $file;
cat @ARGV;
然后我有上面的另一个脚本,它打印目录中所有文件的名称。所以这就是我到目前为止尝试获取目录中的所有文件然后打印所有这些文件的内容:
#!/usr/bin/perl
use strict;
use warnings;
sub print_file
my $file = shift;
open(my $FILE, $file)
or die $!;
while (my $line = <$FILE>)
print $line;
sub print_dir
my $dir = shift;
my @files = glob "$dir/*";
while (my $dir = shift)
foreach my $file (@files)
print_file "$file";
print_dir @ARGV;
显然它不起作用,也没有错误消息。
【问题讨论】:
您无缘无故地在文件名中添加了换行符。"$file\n"
应该是 $file
。
注意:为了代码的完整性,如果文件是打开的,一旦使用了文件处理程序就应该关闭(perl 会为你做这件事,尽管对于干净的代码,文件句柄还是应该关闭)。
注意:在最后一个代码示例中while (my $dir = shift)
可能会返回您不打算接收的内容(您已经在进入子程序时转移了参数)。
注意:如果你打算print $var . "\n"
,那么 perl 提供了一个替代的say $var 来简化代码的可读性。
【参考方案1】:
您无缘无故地在文件名中添加了换行符。
print_file "$file\n";
应该是
print_file $file;
顺便说一句,无用使用全局变量(如FILE
)是一种不好的做法。最好检查 open
是否有错误,因为它很容易出现错误。
open my $FILE, $file
or die "Can't open \"$file\": $!\n";
while (my $line = <$FILE>)
...
有了你的错误,这会输出类似
Can't open "./some_file
": No such file or directory
【讨论】:
【参考方案2】:以下代码 sn-ps 为您的练习演示了两种可能的解决方案。
Perl 代码可以非常简洁地表达所需的算法(原理: 简洁是智慧的灵魂)。
注意 1:代码验证传递的参数是一个目录
注2:代码跳过目录内容的输出,因为它不是文件
use strict;
use warnings;
use feature 'say';
print_dir($_) for @ARGV;
sub print_dir
my $dir = shift;
die "$dir isn't a directory" unless -d $dir;
say for glob("$dir/*");
修改代码以打印文件内容
use strict;
use warnings;
use feature 'say';
print_dir($_) for @ARGV;
sub print_dir
my $dir = shift;
die "$dir isn't a directory" unless -d $dir;
for my $fname ( glob("$dir/*") )
next if -d $fname; # skip directories
say "\n" . '-' x 25
. "\n" . $fname
. "\n" . '-' x 25;
open my $fh, '<', $fname
or die "Couldn't open $fname";
print while <$fh>;
close $fh;
参考:
-X file test glob open die say perlvar 教程:Perl file test operators 教程:Perl special variables推荐:
Learn Perl Perl Documentation Perl Library Free Perl Books【讨论】:
以上是关于如何修改这个 Perl 子例程,以便它使用 print_file 打印文件的内容?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Doxygen 和 Doxygen::Filter::Perl 为 Perl 子例程生成文档?