-4

I have the following code but can it be done in one statement?

open FILE, $file;
while (<FILE>) { $filestr .= $_; }
CJ7
  • 22,579
  • 65
  • 193
  • 321
  • 1
    Possible duplicate of [In Perl, how can I read an entire file into a string?](http://stackoverflow.com/questions/953707/in-perl-how-can-i-read-an-entire-file-into-a-string) – tadman May 19 '16 at 03:37
  • Clearly a different question. I am asking how to do it in one line. I already have the code for reading in a file in my question, so clearly I am not asking that question. – CJ7 May 19 '16 at 03:39
  • Read it into one string, remove the newlines. Why is this hard? – tadman May 19 '16 at 03:41
  • You misunderstood my question. See my edited question. – CJ7 May 19 '16 at 03:46
  • 3
    Delete the newline between the statements and stack them up if you prefer. You're asking some very bizarre questions here. Why does two lines vs. one matter? It certainly doesn't to Perl. – tadman May 19 '16 at 03:49
  • I want to know how to do it in one line of perl code. You don't seem to understand the question. – CJ7 May 19 '16 at 03:52
  • 4
    `open FILE, $file; while () { $filestr .= $_; }` here you go. `:)` – mpapec May 19 '16 at 03:52
  • @Сухой27 You're a rockstar. Exactly! – tadman May 19 '16 at 03:53
  • @tadman OP probably meant `one statement` but that is only a speculation. – mpapec May 19 '16 at 04:01
  • I know this is an old question, but I found an option on some other webpage. This does what you want in one line: `my $inputdata = do{local(@ARGV,$/)="path/to/input.txt";<>}` – steveb Jul 21 '20 at 22:16

3 Answers3

4
open FILE, $file; while (<FILE>) { $filestr .= $_; }

However, the presence of a newline is the last thing that would worry me about that snippet. I'd be more worried about the following:

  • The use of two-arg open,
  • the lack of error checking on that open,
  • the use of a global variables,
  • the lack of use of use strict;, and
  • the poor variable names.

open(my $fh, '<', $qfn)
   or die("Can't open \"$qfn\": $!\n");

my $file; { local $/; $file = <$fh>; }
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

: It looks like you want to slurp a file, would you like me to undef the input record separator?

$ perldoc perlvar # /slurp<enter><copy example code><paste>
$ perl -E '
my $file = "test.txt";
my $content = "";
open my $fh, "<", $file or die $!;
{
  local $/;
  $content = <$fh>;
}
close $fh;
print $content;'

It's never going to be one statement. But anything can be "one line of code" in perl.
So… we're good right? You meant no looping didn't you.

Other stuff to consider:

open my FILE, '<', $file or die $!;
my @filestrs = <FILE>;

Or after cpanm File::Map:

use File::Map qw(map_file);
map_file my $filestr, $file;

Similarly with Path::Tiny:

use Path::Tiny;
my $filestr = path($file)->slurp; # or ->slurp_utf8;

Sort of one line:

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

Fewer statements still:

open(my $fh, '<', $file);
read($fh, $filestr, -s $fh);
dlamblin
  • 43,965
  • 20
  • 101
  • 140
0

I would interpret your question to be:

How can the two statements be written as a single statement without using additional modules or subroutines.

Perl does not prevent you from shooting yourself in the foot, so if you consider semicolon to be the statement separator, the following could be considered as one statement:

open (FILE, $file) and do {$filestr .= $_ while (<FILE>)};

although there is an implicit semicolon at the end of the do block, and this construction should never be used in real code since it prevents checking for open errors the usual way:

open (FILE, $file) or die "Could not open file '$file': $!";
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174