[英]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.