How can I slurp STDIN in Perl?

2020-06-02 08:00发布

I piping the output of several scripts. One of these scripts outputs an entire HTML page that gets processed by my perl script. I want to be able to pull the whole 58K of text into the perl script (which will contain newlines, of course).

I thought this might work:

open(my $TTY, '<', '/dev/tty');

my $html_string= do { local( @ARGV, $/ ) = $TTY ; <> } ;

But it just isn't doing what I need. Any suggestions?

标签: perl
5条回答
该账号已被封号
2楼-- · 2020-06-02 08:08

To get it into a single string you want:

#!/usr/bin/perl -w
use strict;

my $html_string;
while(<>){
   $html_string .= $_;
}

print $html_string;
查看更多
狗以群分
3楼-- · 2020-06-02 08:16

I've always used a bare block.

  my $x;
  {
    undef $/; # Set slurp mode
    $x = <>;  # Read in everything up to EOF
  }
  # $x should now contain all of STDIN
查看更多
女痞
4楼-- · 2020-06-02 08:21

tl;dr: see at the bottom of the post. Explanation first.

practical example

I’ve just wondered about the same, but I wanted something suitable for a shell one-liner. Turns out this is (Korn shell, whole example, dissected below):

print -nr -- "$x" | perl -C7 -0777 -Mutf8 -MEncode -e "print encode('MIME-Q', 'Subject: ' . <>);"; print

Dissecting:

  • print -nr -- "$x" echos the whole of $x without any trailing newline (-n) or backslash escape (-r), POSIX equivalent: printf '%s' "$x"
  • -C7 sets stdin, stdout, and stderr into UTF-8 mode (you may or may not need it)
  • -0777 sets $/ so that Perl will slurp the entire file; reference: man perlrun(1)
  • -Mutf8 -MEncode loads two modules
  • the remainder is the Perl command itself: print encode('MIME-Q', 'Subject: ' . <>);, let’s look at it from inner to outer, right to left:
    • <> takes the entire stdin content
    • which is concatenated with the string "Subject: "
    • and passed to Encode::encode asking it to convert that to MIME Quoted-Printable
    • the result of which is printed on stdout (without any trailing newline)
  • this is followed by ; print, again in Korn shell, which is the same as ; echo in POSIX shell – just echoïng a newline.

tl;dr

Call perl with the -0777 option. Then, inside the script, <> will contain the entire stdin.

complete self-contained example

#!/usr/bin/perl -0777
my $x = <>;
print "Look ma, I got this: '$x'\n";
查看更多
Anthone
5楼-- · 2020-06-02 08:27
my @lines = <STDIN>;

or

my $str = do { local $/; <STDIN> };
查看更多
太酷不给撩
6楼-- · 2020-06-02 08:28

I can't let this opportunity to say how much I love IO::All pass without saying:

♥ ♥ __ "I really like IO::All ... a lot" __ ♥ ♥

Variation on the POD SYNOPSIS:

use IO::All;
my $contents < io('-') ;
print "\n printing your IO: \n $contents \n with IO::All goodness ..." ;

Warning: IO::All may begin replacing everything else you know about IO in perl with its own insidious goodness.

查看更多
登录 后发表回答