Reputation: 1848
This post demonstrates how one can read from STDIN
or from a file, without using the null filehandle (i.e., while(<>)
). However, I'd like to know how can one address situations where input may come from files, STDIN
, or both simultaneously.
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(<>)
?
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.
Upvotes: 0
Views: 830
Reputation:
Here is an idea based on Tim's that checks if STDIN has something to read (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.
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
hello world
$> script.pl < <(echo "hello world")
hello world
$> script.pl <(echo "hello world")
hello world
$> script.pl <<< "hello world"
hello world
$> script.pl
$>
Upvotes: 1
Reputation: 385764
This was already answered by the Answer to which the question links.
@ARGS = '-' if !@ARGV;
for my $qfn (@ARGV) {
open($fh, $qfn);
while (<$fh>) {
...
}
}
Upvotes: 0
Reputation: 5664
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>) {
...
}
Upvotes: 1