简体   繁体   English

如何不使用`while(<>)`来读取STDIN和作为命令行参数传递的文件?

[英]How can I read from both STDIN and files passed as command line arguments without using `while(<>)`?

This post demonstrates how one can read from STDIN or from a file, without using the null filehandle (ie, while(<>) ). 这篇文章演示了如何在不使用空文件句柄(即while(<>) )的情况下从STDIN 文件中进行读取。 However, I'd like to know how can one address situations where input may come from files, STDIN , or both simultaneously. 但是,我想知道如何解决输入可能来自文件, STDIN或同时来自两者的情况。

For instance, the <> syntax can handle such a situation, as demonstrated by the following minimal example: 例如, <>语法可以处理这种情况,如以下最小示例所示:

$ echo -e 'a\nb\nc' | \
  while read x; do echo $x > ${x}".txt"; done; echo "d" | \
  perl -e "while(<>) {print;}" {a,b,c}.txt -
a
b
c
d

How can I do this without using while(<>) ? 不使用while(<>)怎么办?

I want to avoid using <> because I want to handle each file independently, rather than aggregating all input as a single stream of text. 我想避免使用<>因为我想独立处理每个文件,而不是将所有输入汇总为单个文本流。 Moreover, I want to do this without testing for eof on every line of input. 此外,我想这样做而不在每一行输入上测试eof

If you want to handle each file independently of the others, you should loop over the arguments that have been given and open each file in turn: 如果要独立处理每个文件,则应遍历已给定的参数并依次打开每个文件:

for (@ARGV) {
    open(my $fh, '<', $_) || die "cannot open $_";
    while (<$fh>) {
        ... process the file here ...
    }
}
# handle standard input
while (<STDIN>) {
    ...
}

Here is an idea based on Tim's that checks if STDIN has something to read ( NON BLOCKING STDIN ). 这是基于Tim的想法,它检查STDIN是否有要读取的内容( NON BLOCKING STDIN )。 This is useful if you don't really care about a user entering input manually from STDIN yet still want to be able to pipe and redirect data to the script. 如果您不太在意用户从STDIN手动输入输入,但仍然希望能够通过管道将数据重定向到脚本,这将很有用。

File: script.pl

#!/usr/bin/env perl 

use IO::Select;

$s = IO::Select->new();
$s->add(\*STDIN);
if ($s->can_read(0)) { push @ARGV, "/dev/stdin"; } 

for (@ARGV) {
    open(IN, "<$_") || die "** Error opening \"$_\": $!\n";
    while (<IN>) {
        print $_
    }
}

$> echo "hello world" | $>回声“你好世界” | script.pl script.pl
hello world 你好,世界

$> script.pl < <(echo "hello world") $> script.pl <<(回显“ hello world”)
hello world 你好,世界

$> script.pl <(echo "hello world") $> script.pl <(回显“ hello world”)
hello world 你好,世界

$> script.pl <<< "hello world" $> script.pl <<<“ hello world”
hello world 你好,世界

$> script.pl $> script.pl
$> $>

This was already answered by the Answer to which the question links. 问题所链接到的答案已经回答了这一问题。

@ARGS = '-' if !@ARGV;

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

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

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

相关问题 如何让Perl脚本接受来自STDIN和命令行参数的参数? - How can I get a Perl script to accept parameters from both STDIN and command line arguments? Perl:使用Getopt :: Long从命令行和[piped STDIN | file]中获取参数 - Perl: Take arguments from both command line and [piped STDIN|file], using Getopt::Long 如何在Perl中从命令行读取两个文件? - How can I read two files from command line in Perl? 如何从perl中的stdin和文件中解压缩透明gzip? - How can I do a transparent gzip uncompress from both stdin and files in perl? 如何强制 perl 仅从 stdin 而不是从命令行上的文件处理 args? - How can I force perl to process args ONLY from stdin and not from a file on command line? 如何从命令行为子例程传递 arguments - How can I pass arguments for a subroutine from the command line 如何使用命令行参数从bash运行perl脚本? - How can I run a perl script from bash using command line arguments? 使用while(&lt;&gt;)ARGV [1]格式的perl命令行参数,可能使用shift命令吗? - Using perl command line arguments in the format of both while(<>) ARGV[1], possibly using a shift command? 如何解析命令行参数? - How can I parse command line arguments? 传递命令行参数以及来自STDIN的Perl脚本输入? - Pass command line arguments as well as input from STDIN for Perl script?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM