繁体   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