簡體   English   中英

可以編寫一個Perl腳本來從(1)文件,(2)stdin,(3)重定向中的任何一個接收數據嗎?

[英]can a perl script be written to receive data from any of (1) file, (2) stdin, (3) redirect?

幾種unix實用程序,例如fmt,head和cat,可以通過以下三種方式中的任何一種來接收數據: 來自標准輸入的管道; 或重定向“ <”。 例如:

printf '%b' 'dog \ncat \nrat\n' > dogcatrat
fmt dogcatrat
cat dogcatrat  | fmt
fmt < dogcatrat

可以編寫一種功能相同的perl腳本嗎? 還是有充分的理由不嘗試這樣做? “標准輸入的管道”是引用以cat開頭的代碼行的正確方法嗎?

我想編寫myfmt.pl,以這三種方式中的任何一種使用。

默認情況下, ARGV特殊文件句柄將執行此操作。 當沒有給定句柄時,它也是readline(也稱為<><<>>運算符)使用的句柄。 因此,這實際上在Perl腳本中很常見。

#!/usr/bin/env perl
use 5.022;
use warnings;
while (my $line = <<>>) {
  # $line from one of the filenames passed as an argument, otherwise STDIN
  # $ARGV is the current filename, or - when reading from STDIN
}

您可以使用<>運算符來支持較早版本的Perl,但是如果可用, Perl 5.22中添加<<>>運算符是更好的選擇,因為標准的<>運算符允許傳遞諸如date|類的奇怪內容date| 運行進程而不是讀取文件。

為了在支持較舊版本的Perl時更安全的僅文件名操作,可以使用ARGV :: readonly或模擬<<>>運算符,如下所示:

#!/usr/bin/env perl
use strict;
use warnings;
unshift @ARGV, '-' unless @ARGV;
while (my $file = shift) {
  my $fh;
  if ($file eq '-') {
    $fh = \*STDIN;
  } else {
    open $fh, '<', $file or die "open $file failed: $!";
  }
  while (my $line = <$fh>) {
    # ...
  }
}

(從技術上講, <<>>運算符也不允許傳遞-作為讀取STDIN的參數,但是如果要允許它,則由您選擇。)

似乎以下腳本可以滿足要求。

#!/usr/bin/perl
use strict;
use warnings;
use 5.18.2;
local $/ = ""; # input record separator: one paragraph at a time
while (<>) {
    print;
    print "\n";
    say '-' x 30;
}

例:

printf '%b' 'dog \ncat \nrat\n' > aaa
try.pl aaa
cat aaa | try.pl
try.pl < aaa

暫無
暫無

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

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