user5079076
user5079076

Reputation:

Perl delete newline characters from matched string

I am trying to parse some source files and am stuck with this problem. I am searching to match a particular string which has "<<<" and ">>>" in it, and I am trying to delete all newline characters starting from when it finds the above symbols till it encounters the first ";" symbol. Any help will be much appreciated.

This is what I am trying to do:

Input:

... lines of code 
func1 <<< abc, xyz >>> ( str1,
                         str2,
                         str3);
... lines of code

Output:

... lines of code
func1 <<< abc, xyz >>> (str1, str2, str3);
... lines of code

The variables func1, abc, xyz, str1, str2, str3 can all vary.

Thanks in advance.

EDIT:

This is what I have tried and so far it only prints the same pattern as the input.

while (<$fh>) { 
  if (/\<\<\<.*\>\>\>/) {
     while ($_ !~ /\)\s*\;/) {
           chomp $_;
           $_ = <$fh>;
     }
     print $_;
   }
 }

EDIT 2:

Problem has been resolved. See answers.

Upvotes: 0

Views: 145

Answers (3)

Sobrique
Sobrique

Reputation: 53478

Assuming we're talking compressing a statement that contains <<< and as far as ;:

#!/usr/bin/perl
use strict;
use warnings;

while ( <DATA> ) {
    if ( m/<<</ .. m/\);$/ ) {
         s/\s+/ /g;
         s/;\s*$/;\n/g;
    }
    print;
}

__DATA__
... lines of code 
func1 <<< abc, xyz >>> ( str1,
                         str2,
                         str3);
... lines of code
  • We use the range operator to detect if we are between <<< and \);$
  • if we are, we replace whitespace and linefeeds with single spaces.
  • And we do then need to reinsert the trailing linefeed after the ;

This outputs:

... lines of code 
func1 <<< abc, xyz >>> ( str1,  str2,  str3);
... lines of code

Upvotes: 0

svsd
svsd

Reputation: 1869

This should work:

perl -npe 'if (/<<<.*?>>>/../;/) { chomp unless /;/ }' filename

Here's what it does:

  1. Loop through all lines in the file (the -n option)
  2. Match all lines between (and including) <<<.*?>>> and ; and remove newlines from those. This is not done for the line containing ;.
  3. Print all the lines (the -p option)

Upvotes: 0

Amadan
Amadan

Reputation: 198314

my @long, $end;
while (<>) {                               # read a line
  if (/<<<.*>>>/ .. ($end = /;/)) {        # if needs joining,
    s/^\s+|\s+$//g;                        # trim it
    push @long, $_;                        # add to list
    print join(' ', @long) . "\n" if $end; # paste and print if at end
  } else {                                 # if doesn't need joining,
    print;                                 # just print without changes
  }
}

Upvotes: 3

Related Questions