Eugene S
Eugene S

Reputation: 6910

Creating a multi-line variable in Perl

Following my other question here..

I have the following piece of code where I read the contents of a webpage line by line, trying to match a certain pattern and if matched, write it to a file:

foreach my $line (split qr/\R/, $mech->content) {
    if ($line=~ m/t\/([A-Z]+)/){
        print $fileHandle "$1\n";
    }
}

I wonder whether it possible to append the matching lines to another multi-line variable and write it to a file only when the loop is finished.

The reason I want it to be that way is because I want to use the following subroutine to save data to a file, rather than doing it directly:

writeToFile("fileName.tmp","path",data);

This is a subroutine I wrote, which apart of just saving the data in a file, also checks the following:

  1. Whether the specified path already exists (and creates it if needed)
  2. If the file already exist on disk, compare it to the one which is about to be written (and write it only in case the files are different)

So if I'll be able to create this additional variable, I will have one less file to write to a disk.

Upvotes: 1

Views: 4172

Answers (3)

DVK
DVK

Reputation: 129403

  1. You can do it by string concatenation, inside your loop you simply replace print with

    $data .= "$1\n"; 
    # Same as $data = $data . "$1\n";
    
  2. Or use the magic of Perl's map to build the multiline string, without having either a loop or an if:

    my $data = join "", 
                    map { /t\/([A-Z]+)/ ? "$1\n" : "" } 
                    split(qr/\R/, $mech->content);
    
  3. Or, you don't even have to go through the pain of splitting and joining.

    Simply treat your multiline string as a single string (/g modifier lets the regex match again and again), and replace your entire loop with just 3 lines:

    my $data = $mech->content();
    $data =~ s/t\/([A-Z]+)/$1\n/g;
    writeToFile("fileName.tmp", "path", $data);
    

Upvotes: 4

ikegami
ikegami

Reputation: 385849

Just replace

open(my $fileHandle, ...) or ...;

...

   print $fileHandle "$1\n";

with

my $data = '';

...

   $data .= "$1\n";

to append the output to a string instead of sending it to a file handle.

Upvotes: 1

It's simple - you can append characters by using .= operator (which is comboned assignment (=) and concatenation (.):

my $data = "";
while (my $line = ...) {
    ...
    $data .= $line . "\n";
}
writeToFile("fileName.tmp", "path", $data);

Upvotes: 1

Related Questions