AnewSmurf has asked for the wisdom of the Perl Monks concerning the following question:

Hi All, Here is a sample of variable
$lines = "The kernel packages contain the Linux kernel, the core of any Linux
operating system.

Security fixes:

* The maximum file offset handling for ext4 file systems could allow a
local, unprivileged user to cause a denial of service. (CVE-2011-2695,
Important)

* IPv6 fragment identification value generation could allow a remote
attacker to disrupt a target system's networking, preventing legitimate
users from accessing its services. (CVE-2011-2699, Important)

* A malicious CIFS (Common Internet File System) server could send a
specially-crafted response to a directory read request that would result in
a denial of service or privilege escalation on a system that has a CIFS
share mounted. (CVE-2011-3191, Important)
";
I would like to extract content between * and (CVE-.*) and removing return between line. For example:
A malicious CIFS (Common Internet File System) server could send a specially-crafted response to a directory read request that would result in a denial of service or privilege escalation on a system that has a CIFS share mounted. (CVE-2011-3191, Important)
I've the code to extract the text between * and (CVE..) when there are no \n.
  • Comment on Remove return on multiple lines between 2 characters

Replies are listed 'Best First'.
Re: Remove return on multiple lines between 2 characters
by tybalt89 (Monsignor) on Jul 18, 2017 at 21:14 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1195378 use strict; use warnings; my $lines = "The kernel packages contain the Linux kernel, the core of + any Linux operating system. Security fixes: * The maximum file offset handling for ext4 file systems could allow a local, unprivileged user to cause a denial of service. (CVE-2011-2695, Important) * IPv6 fragment identification value generation could allow a remote attacker to disrupt a target system's networking, preventing legitimat +e users from accessing its services. (CVE-2011-2699, Important) * A malicious CIFS (Common Internet File System) server could send a specially-crafted response to a directory read request that would resu +lt in a denial of service or privilege escalation on a system that has a CIF +S share mounted. (CVE-2011-3191, Important) "; my @content = $lines =~ tr/\n/ /r =~ /\*\s*([^*]*?)\s*\(CVE/g; use Data::Dump 'pp'; pp \@content;
Re: Remove return on multiple lines between 2 characters
by shmem (Chancellor) on Jul 19, 2017 at 08:37 UTC

    TIMTOWTDI... you could open a file handle on a reference to $lines as in-memory file and read from there in paragraph mode:

    $lines = "The kernel packages contain the Linux kernel, the core of an +y Linux operating system. Security fixes: * The maximum file offset handling for ext4 file systems could allow a local, unprivileged user to cause a denial of service. (CVE-2011-2695, Important) * IPv6 fragment identification value generation could allow a remote attacker to disrupt a target system's networking, preventing legitimat +e users from accessing its services. (CVE-2011-2699, Important) * A malicious CIFS (Common Internet File System) server could send a specially-crafted response to a directory read request that would resu +lt in a denial of service or privilege escalation on a system that has a CIF +S share mounted. (CVE-2011-3191, Important) "; { local $/ = "\n\n"; open my $fh, "<", \$lines; while( <$fh> ) { if (/\(CVE-/) { s/\n//sg; print ">$_<\n"; } } } __END__ >* The maximum file offset handling for ext4 file systems could allow +alocal, unprivileged user to cause a denial of service. (CVE-2011-269 +5,Important)< >* IPv6 fragment identification value generation could allow a remotea +ttacker to disrupt a target system's networking, preventing legitimat +eusers from accessing its services. (CVE-2011-2699, Important)< >* A malicious CIFS (Common Internet File System) server could send as +pecially-crafted response to a directory read request that would resu +lt ina denial of service or privilege escalation on a system that has + a CIFSshare mounted. (CVE-2011-3191, Important)<
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      paragraph mode ... local $/ = "\n\n";

      Just wanted to point this out from $/:

      Setting it to "\n\n" means something slightly different than setting to "", if the file contains consecutive empty lines. Setting to "" will treat two or more consecutive empty lines as a single empty line. Setting to "\n\n" will blindly assume that the next input character belongs to the next paragraph, even if it's a newline.
        Just wanted to point this out from $/:

        Good point! But irrelevant in this case, since all newline characters are removed from the matching paragraph. So even if there were multiple leading "\n" characters per record, the output would be the same.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Remove return on multiple lines between 2 characters
by Anonymous Monk on Jul 18, 2017 at 20:51 UTC
    I've the code to extract the text between * and (CVE..) when there are no \n.

    Show us? and try adding /s to the regex, /^\*\s+(.+?)\s*\(CVE/smg

Re: Remove return on multiple lines between 2 characters
by karlgoethebier (Abbot) on Jul 18, 2017 at 21:34 UTC

    If i understood you right you probably want something like this: say for grep { /\*.+/ } split /\n\n/, $lines;

    Update: I missed something:

    my @content = map { s/\n+/ /g; s/ {2,}/ /g; s/\* //; $_ } grep { /\*.+/ } split /\n\n/, $lines;

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Remove return on multiple lines between 2 characters
by AnewSmurf (Initiate) on Jul 18, 2017 at 21:15 UTC
    I think I'm close for my solution....
    open(FILE, "<" , \$lines); while (<FILE>) { chomp; # strip record separator if(/\)$/) { $f=2; } if (/^\*/) { $f=1; } if ($f == 1) { print $_; } if ($f==2) { chomp; # strip record separator print " " . $_ . "\n"; } }
    gets me ...
    * The maximum file offset handling for ext4 file systems could allow alocal, unprivileged user to cause a denial of service. (CVE-2011-2695, Important)
     
    * IPv6 fragment identification value generation could allow a remoteattacker to disrupt a target system's networking, preventing legitimate users from accessing its services. (CVE-2011-2699, Important)
     
    * A malicious CIFS (Common Internet File System) server could send aspecially-crafted response to a directory read request that would result ina denial of service or privilege escalation on a system that has a CIFS share mounted. (CVE-2011-3191, Important)
    
      #!/usr/bin/perl # http://perlmonks.org/?node_id=1195378 use strict; use warnings; my $lines = "The kernel packages contain the Linux kernel, the core of + any Linux operating system. Security fixes: * The maximum file offset handling for ext4 file systems could allow a local, unprivileged user to cause a denial of service. (CVE-2011-2695, Important) * IPv6 fragment identification value generation could allow a remote attacker to disrupt a target system's networking, preventing legitimat +e users from accessing its services. (CVE-2011-2699, Important) * A malicious CIFS (Common Internet File System) server could send a specially-crafted response to a directory read request that would resu +lt in a denial of service or privilege escalation on a system that has a CIF +S share mounted. (CVE-2011-3191, Important) "; for ( $lines =~ tr/\n/ /r =~ /\*\s*([^*]*\(CVE.*?\))/g ) { print "$_\n\n"; }
        Thanks your solution seems better. It works perfectly.