Lazer
Lazer

Reputation: 94930

How to instruct Perl to consider multiple lines broken on a particular character as a single line?

For example, I have a txt file with multi line calls broken on an ampersand.

command1

command2

execute myscript &
        opt1=val1 &
        opt2=val2

...

While opening the file, is there a way to tell Perl to consider these three lines as if it were a single line and ignore the &?

Upvotes: 1

Views: 96

Answers (3)

Greg Bacon
Greg Bacon

Reputation: 139621

I assume your input is of a reasonable size, so read the whole thing into a scalar, clean it up, and then process the friendlier result.

#! /usr/bin/env perl

use strict;
use warnings;

sub read_input {
  my($fh) = @_;
  local $/;
  scalar <$fh>;
}

my $commands = read_input \*DATA;

$commands =~ s/&\n//g;
print $commands;

__DATA__
command1

command2

execute myscript &
        opt1=val1 &
        opt2=val2

Output:

command1

command2

execute myscript         opt1=val1         opt2=val2

Upvotes: 0

cjm
cjm

Reputation: 62109

Not when opening the file. But it's not too hard to join them while reading:

open(my $in, '<', 'file.txt') or die;
while (<$in>) {
  $_ .= <$in> while s/&\s*\z//;

  # $_ now contains a complete record
  ...
}

Upvotes: 5

Robert P
Robert P

Reputation: 15978

If you always have multiple newlines between records, consider using the Record Separator to read them. Then, you can use a quick check for the &, and perform a split/join:

use English '-no_match_vars'; 

sub read_records {
    local $RS = "\n\n";  # or,  for the machoistic,  $/ works too without English
    ... # open the file
    while (my $record = <$fh>) {
        chomp $record;               # uses $RS for what to remove, nice!
        if ($record =~ /&\s*$/ms) {  # & at the end of *any* line (w/only spaces)
            $record = join ' ', split /\s*&\s+/, $record; # pull them out
        }
        ... # do something with the record
    }
}

Upvotes: 0

Related Questions