简体   繁体   English

perl:不使用while(<>)即可读取文件和/或stdin

[英]perl: reading from a file and/or stdin without using while(<>)

For cases where one wishes to avoid the useful while(<>) syntax and manage file input manually, how does one handle the operation of reading from a list of files and/or STDIN ? 对于希望避免使用while(<>)语法并手动管理文件输入的情况,如何处理从文件列表和/或STDIN中读取的操作? To read from files, one can simply iterate through @ARGV , opening each element in turn (eg, my $file=shift @ARGV; open(my $fh,'<',$file); while(<$fh>) {...}; close($fh); . To read from standard input, one can simply use while(<STDIN>) { ...} . However, assuming the programmer expects similar types of data to be provided through STDIN and file arguments, the body of code within each while loop would have to be duplicated. I have tried unsuccessfully to assign STDIN to a filehandle (eg, my $fh = \\*STDIN or my $fh = *STDIN{IO} , each of which I have seen suggested elsewhere on this website). In essence, I would like to iterate through all files as well as STDIN and treat the input from each identically, but without using the handy while(<>) syntax. Could you please sketch a solution to this problem? Thank you. 要读取文件,可以简单地遍历@ARGV ,依次打开每个元素(例如, my $file=shift @ARGV; open(my $fh,'<',$file); while(<$fh>) {...}; close($fh);要从标准输入中读取内容,可以简单地使用while(<STDIN>) { ...} 。但是,假设程序员希望通过STDIN提供类似类型的数据。和文件参数,每个while循环中的代码正文都必须重复。我尝试将STDIN分配给文件句柄(例如, my $fh = \\*STDINmy $fh = *STDIN{IO} ,但均失败)本质上,我想遍历所有文件以及STDIN并相同地对待每个文件的输入,但不使用方便的while(<>)语法。画出解决这个问题的方法?谢谢。

With two-arg open (like <> uses), you could do 打开两个参数(如<>使用),您可以执行

@ARGS = '-' if !@ARGV;

for my $qfn (@ARGV) {
    open($fh, $qfn);

    while (<$fh>) {
       ...
    }
}

Which three-arg open , I might do 哪个三个参数open ,我可能会做

@ARGV = \*STDIN if !@ARGV;

for my $qfn (@ARGV) {
    my $fh;
    if (ref($qfn)) {
       $fh = $qfn;
    } else {
       open($fh, '<', $qfn);
    }

    while (<$fh>) {
       ...
    }
}

Another way (if you can use CPAN modules) is to use IO::All . 另一种方法(如果可以使用CPAN模块)是使用IO :: All

Read a file into a scalar variable: 将文件读入标量变量:

my $content1 < io('file1');

Another way to do it with IO::ALL: 使用IO :: ALL的另一种方法:

my $content2 = io('file1')->slurp;

Or if you want it in an array, with each line as an element: 或者,如果您希望将其放在一个数组中,并以每行作为元素:

my @lines = io('file1')->slurp;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM