0

I have a while loop that should read lines either from STDIN or from file.

However, I'm not sure if this is possible to include if statements in the while loop to make it read lines from either STDIN or file.

Is there a way to manipulate on which lines while loop is operating (e.g. where lines are coming from)?

For example, I have set some keywords to know where the input is coming from based on what line arguments are provided and opened file to read lines.

I understand that one of the ways to solve this issue may be put STDIN into array first. The solution should not user arrays.

if ($argCount == 1) {
    $keyword = "input";
}
else {
    $keyword = "file";
    open ($out, '<', "temp.txt") or die "Cannot open file";
}

while ( ($line = <STDIN> && &keyword eq "input") || ($line = <$out> && $keyword eq "file") ) {
    print "$line\n";
    # do something with lines
}
     

In the above example, if STDIN, then it its printing only first line and does not move further; if file, then its just waiting for input on STDIN. I'm sure this is not the right way.

Expected output would be print out all lines from either STDIN or file. If keyword was set to "input", then $line = <STDIN> and prints all lines from STDIN. If keyword was set to "file, then $line = <$out> and prints all lines from the file.

4
  • 2
    I think you just want the "diamond operator": while(<>) { ... } reads from file(s) mentioned on the command line, or stdin if no files are provided. Commented Apr 24, 2021 at 0:54
  • @JimGarrison while (<>) reads starting from $ARGV[0], but what if the first argument is not a file? Commented Apr 24, 2021 at 0:56
  • You can change @ARGV to be whatever you need at any point before invoking the diamond operator, so: shift @argv; before the while. Commented Apr 24, 2021 at 1:02
  • Re "what if the first argument is not a file?", Use something like Getopt::Long. It will remove from @ARGV the options it parses, leaving the just file(s). Commented Apr 24, 2021 at 1:03

1 Answer 1

2
my $fh;
if (...) {
   $fh = \*STDIN;
} else {
   open($fh, '<', ...)
      or die(...);
}

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

That said, you should simply be using

while (<>) {
   ...
}

If a file name is provided on the command line, the name file will be used. If not, STDIN will be used.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.