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

以编程方式从STDIN或Perl中的输入文件读取,perl,stdin,Perl,Stdin,以编程方式从stdin或Perl中的输入文件(如果提供)中读取数据的最灵活方法是什么?您需要使用运算符: while (<>) { print $_; # or simply "print;" } while(){ 打印$或简单地“打印” } 可压实至: print while (<>); while()打印; 任意文件: open F, "<file.txt" or die $!; while (<F>) { print $_;

以编程方式从stdin或Perl中的输入文件(如果提供)中读取数据的最灵活方法是什么?

您需要使用运算符:

while (<>) {
    print $_; # or simply "print;"
}
while(){
打印$或简单地“打印”
}
可压实至:

print while (<>);
while()打印;
任意文件:

open F, "<file.txt" or die $!;
while (<F>) {
    print $_;
}
close F;
openf,“
在这里,您只需将第一个示例中
{}
之间的代码放入第二个示例中的
'
,如果(my$file=shift){#如果指定了文件,则从该文件读取
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(<>);
}
打开(我的$fh,Do

$userinput=;#读取stdin并将其放入$userinput中
chomp($userinput)#剪切返回/换行字符

如果只想读取一行,则提供一个命名变量:

foreach my $line ( <STDIN> ) {
    chomp( $line );
    print "$line\n";
}
foreach my$行(){
chomp($line);
打印“$line\n”;
}
要读取文件,请按如下方式导入:

program.pl < inputfile
program.pl
在某些情况下,“最灵活”的方法是利用。它使用
while()
循环隐式地包装代码,并灵活地处理输入

slickestWay.pl
中:

#!/usr/bin/perl -n BEGIN: { # do something once here } # implement logic for a single line of input print $result; 现在,根据您的输入,执行以下操作之一:

  • 等待用户输入

    ./slickestWay.pl
    
  • 从参数中命名的文件读取(无需重定向)

  • 使用管道

    someOtherScript | ./slickestWay.pl 
    
  • 如果需要初始化某种类型的面向对象接口,如Text::CSV或类似的接口,则需要使用
    -M
    将其添加到shebang中,则需要使用
    开始

    -l
    -p
    也是您的朋友。

    如果有原因您不能使用上面ennuikiller提供的简单解决方案,那么您将不得不使用Typeglobs来操作文件句柄。这是一个更大的工作。此示例从
    $ARGV[0]
    中的文件复制到
    $ARGV[1]中的文件
    。如果未指定文件,则分别默认为
    STDIN
    STDOUT

    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($_);
    }
    
    使用英语;
    我的美元;
    我的美元用完了;
    如果($#ARGV>=0){
    除非(未结($in,“,$ARGV[1])){
    die“无法打开$ARGV[1]进行写入。”;
    }
    }
    否则{
    $out=*STDOUT;
    }
    while($\=){
    $out->打印($\ux);
    }
    
    以下是我如何制作一个脚本,它可以接受命令行输入,也可以重定向文本文件。

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

    这将把文件的内容重新分配给@ARGV,从那里您只需处理@ARGV,就像有人包含命令行选项一样。

    警告

    如果没有重定向文件,程序将处于空闲状态,因为它正在等待来自STDIN的输入。


    我还没有找到一种方法来检测一个文件是否被重定向,以消除STDIN问题。

    +1+挑剔:“将从命令行上连续指定的一个或多个文件中读取”…而您所需要做的就是写入
    @ARGV=“/path/to/some/file.ext”“;
    并且它读取文件——因此您甚至可以在某些条件下编写一个默认文件。如果您的脚本非常短,您可以使用-n或-p选项来设置perl,并在命令行上指定您的处理:
    perl-n-e'$\uUUUc=uc($\uUUc);print;'yourfile
    。使用-p而不是-n,perl会在末尾自动打印$。当然,您可以一次“咕噜”所有内容:
    my@slurp=;foreach my$行(@slurp){…}
    您为什么不使用
    while(my$line=)这样的名称命名读取行{…
    ?普通
    操作员将自动查找并读取任何文件在命令行上给出。不需要使用
    if
    。您也不需要描述
    shift
    在这里做了什么+1,以避免非常常见的速记不可读的Perl code-1,因为foreach将吞掉整个文件。最好在while循环中分配给该行。此外,Perl对裸角b具有内置的神奇行为球拍,所以你应该说while(my$line=)。那么就不需要重定向了。第一行应该是
    foreach my$line(){
    我同意@MikeKulls。如果Perl脚本不可读,那不是Perl的错。这里应该归咎于程序员!重读这个问题,这个回答是不正确的,因为它只读取stdin,不读取命令行上指定的文件。ennuikiller的答案是正确的,尽管我将它写成
    while(my$line=){print$line;}
    @MikeKulls不应该是
    while(my$line=,defined$line){…}
    while(){my$line=$}
    以避免停在空行上?+1是一种如果命令行上没有提供要读取的文件名而在其他地方提供的方法(在某些变量中,从配置文件等读取-您只需将
    $ARGV[0]
    等替换为其他变量)如果所有其他答案都失败…或者,为了阅读,只需将文件名
    反移位到
    @ARGV
    ,并使用菱形运算符
    。这是一种很酷的方法,但不是OP要求的方法。这使得可以将单个文件名作为参数传递,其中的内容用作命令行参数。OP寻找不同的东西。还有,为什么神秘的
    $#ARGV<1
    而不是(我认为)更清晰的
    @ARGV==1
    ?只从STDIN读取,而不是从指定的文件读取。菱形运算符正是OP所要寻找的。
    chmod +x slickestWay.pl
    
    ./slickestWay.pl
    
    ./slickestWay.pl input.txt
    ./slickestWay.pl input.txt moreInput.txt
    
    someOtherScript | ./slickestWay.pl 
    
    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($_);
    }
    
    if ($#ARGV < 1) {
        @ARGV = ();
        @ARGV = <>;
        chomp(@ARGV);
    }