以编程方式从STDIN读取或在Perl中输入文件

syk*_*ker 67 perl stdin

在stl中以编程方式从stdin或输入文件(如果提供)中读取的最简单的方法是什么?

enn*_*ler 81

while (<>) {
print;
}
Run Code Online (Sandbox Code Playgroud)

将从命令行中指定的文件或stdin读取(如果没有给出文件)

如果在命令行中需要此循环构造,则可以使用-n选项:

$ perl -ne 'print;'
Run Code Online (Sandbox Code Playgroud)

在这里,您只需将代码{}从第一个示例放入''第二个示例

  • +1 + nitpick:"将从命令行上连续指定的一个或多个文件中读取" (21认同)
  • ...而你需要做的就是编写`@ARGV ="/ path/to/some/file.ext";`并且它读取文件 - 所以你甚至可以在某些条件下编写默认文件. (4认同)
  • 如果你的脚本非常短,可以使用-n或-p选项来命令perl,并在命令行中指定你的处理:`perl -n -e'$ _ = uc($ _); 打印;' yourfile`.使用-p而不是-n,perl会在最后自动打印$ _. (3认同)
  • 当然,你可以一口气"啜饮"一切:`my @slurp = <>; 预告我的$ line(@slurp){...}` (3认同)

小智 44

这提供了一个命名变量来使用:

foreach my $line ( <STDIN> ) {
    chomp( $line );
    print "$line\n";
}
Run Code Online (Sandbox Code Playgroud)

要读取文件,请将其管道输入:

program.pl < inputfile
Run Code Online (Sandbox Code Playgroud)

  • +1用于避免使用太常见的简写不可读的Perl代码 (10认同)
  • -1因为foreach会淹没整个文件.最好在while循环中分配给该行.此外,Perl具有裸角括号的内置魔法行为,所以你应该说while(my $ line = <>).然后不需要重定向. (4认同)
  • 第一行应该是`foreach my $ line(<STDIN>){`我同意@MikeKulls.如果Perl脚本不可读,那不是Perl的错.程序员应该责怪这里! (3认同)
  • 重新阅读问题此响应是不正确的,因为它仅从 stdin 读取,而未读取在命令行上指定的文件。ennukiller 的答案是正确的,尽管我会将其写为 `while(my $line = &lt;&gt;) { print $line; }`。 (2认同)
  • @MikeKulls不应该是while(我的$ line = &lt;&gt;,定义为$ line){...}`或`while(&lt;&gt;){我的$ line = $ _; }`以避免停在空白行上? (2认同)

Nei*_*est 14

在某些情况下,"最简单"的方式是利用-n开关.它隐式地用while(<>)循环包装你的代码并灵活地处理输入.

slickestWay.pl:

#!/usr/bin/perl -n

BEGIN: {
  # do something once here
}

# implement logic for a single line of input
print $result;

在命令行:

chmod +x slickestWay.pl
Run Code Online (Sandbox Code Playgroud)

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

  1. 等待用户输入

    ./slickestWay.pl
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从参数中命名的文件中读取(不需要重定向)

    ./slickestWay.pl input.txt
    ./slickestWay.pl input.txt moreInput.txt
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用管道

    someOtherScript | ./slickestWay.pl 
    
    Run Code Online (Sandbox Code Playgroud)

BEGIN如果你需要初始化某种面向对象的接口,例如Text :: CSV或其他一些,你可以添加到shebang中,这个块是必要的-M.

-l并且-p也是你的朋友.


el.*_*ado 13

你需要使用<>运算符:

while (<>) {
    print $_; # or simply "print;"
}
Run Code Online (Sandbox Code Playgroud)

哪个可以压缩到:

print while (<>);
Run Code Online (Sandbox Code Playgroud)

任意档案:

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


小智 8

如果有一个原因你不能使用上面ennuikiller提供的简单解决方案,那么你将不得不使用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($_);
}
Run Code Online (Sandbox Code Playgroud)

  • +1 如果要读取的文件名*未*在命令行上提供,而是在其他地方提供(在某些变量中,从配置文件等读取 - 您只需将 `$ARGV[0]` 等替换为其他变量),则 +1 有效所有其他答案都失败了...... (2认同)

Tho*_*ues 6

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

如果你只想读一行