以编程方式从STDIN或Perlinput文件读取

在Perl中用stdin或者input文件(如果提供)以编程方式读取的最明智的方法是什么?

while (<>) { print; } 

将从命令行中指定的文件读取,如果没有给出文件,则从标准input读取

如果你在命令行中需要这个循环结构,那么你可以使用-n选项:

 $ perl -ne 'print;' 

在这里,您只需将第一个示例中的代码放入第二个中的''

这提供了一个命名的variables来处理:

 foreach $line ( <STDIN> ) { chomp( $line ); print "$line\n"; } 

要读取文件,请像这样pipe道:

 program.pl < inputfile 

您需要使用<>运算符:

 while (<>) { print $_; # or simply "print;" } 

哪些可以压缩到:

 print while (<>); 

任意文件:

 open F, "<file.txt" or die $!; while (<F>) { print $_; } close F; 

在某些情况下,“最清晰”的方式是利用-n开关 。 它用一段while(<>)循环隐式地包装你的代码,并灵活地处理input。

slickestWay.pl

 #!/ usr / bin / perl -n

开始: {
   #在这里做一些事情
 }

 #实现单行input的逻辑
打印$结果;

在命令行中:

 chmod +x slickestWay.pl 

现在,根据您的input,请执行以下操作之一:

  1. 等待用户input

     ./slickestWay.pl 
  2. 从参数中命名的文件中读取(不需要redirect)

     ./slickestWay.pl input.txt ./slickestWay.pl input.txt moreInput.txt 
  3. 使用pipe道

     someOtherScript | ./slickestWay.pl 

如果你需要初始化某种面向对象的接口,比如Text :: CSV或者其他一些你可以用-M添加到shebang的方法, BEGIN块是必须的。

-l-p也是你的朋友。

 $userinput = <STDIN>; #read stdin and put it in $userinput chomp ($userinput); #cut the return / line feed character 

如果你只想读一行

如果有一个原因,你不能使用上面的ennuikiller提供的简单的解决scheme,那么你将不得不使用Typeglobs操纵文件句柄。 这是更多的工作。 本示例将从$ARGV[0]的文件复制到$ARGV[1] 。 如果没有指定文件,它分别默认为STDINSTDOUT

 use English; my $in; my $out; if ($#ARGV >= 0){ unless (open($in, "<", $ARGV[0])){ die "could not open $ARGV[0] for reading."; } } else { $in = *STDIN; } if ($#ARGV >= 1){ unless (open($out, ">", $ARGV[1])){ die "could not open $ARGV[1] for writing."; } } else { $out = *STDOUT; } while ($_ = <$in>){ $out->print($_); } 

这里是我做了一个脚本,可以采取任何一个命令行input或文本文件redirect。

 if ($#ARGV < 1) { @ARGV = (); @ARGV = <>; chomp(@ARGV); } 

这将重新分配文件的内容到@ARGV,从那里你只是处理@ARGV,就好像有人包括命令行选项。

警告

如果没有文件被redirect,程序将处于空闲状态,因为它正在等待来自STDIN的input。

我还没有想出一种方法来检测文件是否被redirect,以消除STDIN问题。

无耻地从“ 尼尔最好 ”和“ 罗恩 ”

假设脚本名称是: stdinProcessor.pl

 #!/usr/bin/perl BEGIN: { print "Doing some stuff first\n"; } foreach $line ( <STDIN> ) { chomp($line); print "$line\n"; } # Do something at the exit print "Iteration done\n" 

例:

 $echo '1\n2\n3' | ./stdinProcessor.pl Doing some stuff first 1 2 3 Iteration done 
 if(my $file = shift) { # if file is specified, read from that open(my $fh, '<', $file) or die($!); while(my $line = <$fh>) { print $line; } } else { # otherwise, read from STDIN print while(<>); }