簡體   English   中英

如何修改此 Perl 子例程,以便使用 print_file 打印文件的內容?

[英]How can I modify this Perl subroutine so that it prints the contents of the file, using print_file?

閱讀 Allen B. Downey的《學習 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;

顯然它不起作用,也沒有錯誤消息。

您無緣無故地在文件名中添加了換行符。

print_file "$file\n";

應該

print_file $file;

順便說一句,無用使用全局變量(如FILE )是一種不好的做法。 檢查open是否有錯誤是個好主意,因為它很容易出現錯誤。

open my $FILE, $file
   or die "Can't open \"$file\": $!\n";

while (my $line = <$FILE>) {
   ...
}

有了你的錯誤,這將有 output 類似

Can't open "./some_file
": No such file or directory

以下代碼片段演示了練習的兩種可能解決方案。

Perl代碼可以非常簡潔的表達想要的算法(原則:簡潔是智慧的靈魂)。

注1:代碼驗證傳遞的參數是一個目錄

注2:代碼跳過目錄內容的output,因為它不是文件

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;
    }
}

參考:

推薦:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM