in reply to Re: Join multiple lines in a string based on regex.
in thread Join multiple lines in a string based on regex.

Hi, Here is the O/P that I needed. I probably skipped few lines in my code during my first post .
use strict; use warnings; use Data::Dumper; my %unitMap; my $skipNext; my $count = 0; my $cmd = "somecommand";; open my $fd, "$cmd|" or return \%unitMap; while (my $row = <$fd>) { $row =~ /^$/ and next; $row =~ s/[,|)|(]//g; chomp $row; next if $row =~ /^Smart/g; $row =~ s/^\s+//; if( $row =~ /^unassigned/ ){ $skipNext = 2; next; } if( $skipNext ){ $skipNext--; next; } print "$ow\n";
Below is my Data exactly .
data array A physicaldrive 2C:1:1 port 2C:box 1:bay 1 SAS 1 TB OK physicaldrive 2C:1:2 port 2C:box 1:bay 2 SAS 1 TB OK array B physicaldrive 2C:1:3 port 2C:box 1:bay 3 SAS 1 TB OK physicaldrive 2C:1:4 port 2C:box 1:bay 4 SAS 1 TB OK array C physicaldrive 3C:1:5 port 3C:box 1:bay 5 SAS 1 TB OK physicaldrive 3C:1:6 port 3C:box 1:bay 6 SAS 1 TB OK array D physicaldrive 3C:1:7 port 3C:box 1:bay 7 SAS 1 TB OK physicaldrive 3C:1:8 port 3C:box 1:bay 8 SAS 1 TB OK array E physicaldrive 4C:2:1 port 4C:box 2:bay 1 SAS 1 TB OK physicaldrive 4C:2:2 port 4C:box 2:bay 2 SAS 1 TB OK array F physicaldrive 4C:2:3 port 4C:box 2:bay 3 SAS 1 TB OK physicaldrive 4C:2:4 port 4C:box 2:bay 4 SAS 1 TB OK array G physicaldrive 5C:2:5 port 5C:box 2:bay 5 SAS 1 TB OK physicaldrive 5C:2:6 port 5C:box 2:bay 6 SAS 1 TB OK array H physicaldrive 5C:2:7 port 5C:box 2:bay 7 SAS 1 TB OK physicaldrive 5C:2:8 port 5C:box 2:bay 8 SAS 1 TB OK array I physicaldrive 6C:3:1 port 6C:box 3:bay 1 SAS 1 TB OK physicaldrive 6C:3:2 port 6C:box 3:bay 2 SAS 1 TB OK array J physicaldrive 6C:3:3 port 6C:box 3:bay 3 SAS 1 TB OK physicaldrive 6C:3:4 port 6C:box 3:bay 4 SAS 1 TB OK array K physicaldrive 7C:3:5 port 7C:box 3:bay 5 SAS 1 TB OK physicaldrive 7C:3:6 port 7C:box 3:bay 6 SAS 1 TB OK unassigned physicaldrive 7C:3:7 port 7C:box 3:bay 7 SAS 1 TB OK physicaldrive 7C:3:8 port 7C:box 3:bay 8 SAS 1 TB OK
a) The Aim here is to join lines starting with string array and until it hits the pattern starting with the string array again and join the lines and repeat the same for all the lines in the string . b) The Line containing unassigned and the lines after it should be removed until it hits a line containing the string array at the start of line . c) In my code , I have removed the line containing unassigned and 2 lines after it , But it should remove any number of lines after unassigned until it matches array at the start of the string .
data unassinged... physicaldrive ......... physical dirve ..... physicaldrive...... array

Replies are listed 'Best First'.
Re^3: Join multiple lines in a string based on regex.
by NetWallah (Canon) on Dec 17, 2014 at 06:40 UTC
    Slightly simpler logic..
    use strict; use warnings; my $row =""; my $inarray=0; while (<DATA>) { chomp; if (/^array|^unassigned/){ print "$row\n" if $inarray; $row=$_; $inarray=m/^array/; next; } next unless $inarray; $row .= " $_"; } print "$row\n" if $inarray; __DATA__ ....

            "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams

      Hi, Thanks for sending the code . I have executed the script , But it doesn't give any O/P . The File Handle that I am opening comes from a Command O/P . Here is what I tried .
      my $row =""; my $inarray=0; my $cmd = "Command"; open $fd, "$cmd|" while (<$fd>) { chomp; if (/^array|^unassigned/){ print "$row\n" if $inarray; $row=$_; $inarray=m/^array/; next; } next unless $inarray; $row .= " $_"; } print "$row\n" if $inarray; close($fd);
      The actual Data from the command O/P
      data Smart Array P410i in Slot 0 (Embedded) array A physicaldrive 2C:1:1 (port 2C:box 1:bay 1, SAS, 1 TB, OK) physicaldrive 2C:1:2 (port 2C:box 1:bay 2, SAS, 1 TB, OK) array B physicaldrive 2C:1:3 (port 2C:box 1:bay 3, SAS, 1 TB, OK) physicaldrive 2C:1:4 (port 2C:box 1:bay 4, SAS, 1 TB, OK) array C physicaldrive 3C:1:5 (port 3C:box 1:bay 5, SAS, 1 TB, OK) physicaldrive 3C:1:6 (port 3C:box 1:bay 6, SAS, 1 TB, OK) array D physicaldrive 3C:1:7 (port 3C:box 1:bay 7, SAS, 1 TB, OK) physicaldrive 3C:1:8 (port 3C:box 1:bay 8, SAS, 1 TB, OK) array E physicaldrive 4C:2:1 (port 4C:box 2:bay 1, SAS, 1 TB, OK) physicaldrive 4C:2:2 (port 4C:box 2:bay 2, SAS, 1 TB, OK) array F physicaldrive 4C:2:3 (port 4C:box 2:bay 3, SAS, 1 TB, OK) physicaldrive 4C:2:4 (port 4C:box 2:bay 4, SAS, 1 TB, OK) array G physicaldrive 5C:2:5 (port 5C:box 2:bay 5, SAS, 1 TB, OK) physicaldrive 5C:2:6 (port 5C:box 2:bay 6, SAS, 1 TB, OK) array H physicaldrive 5C:2:7 (port 5C:box 2:bay 7, SAS, 1 TB, OK) physicaldrive 5C:2:8 (port 5C:box 2:bay 8, SAS, 1 TB, OK) array I physicaldrive 6C:3:1 (port 6C:box 3:bay 1, SAS, 1 TB, OK) physicaldrive 6C:3:2 (port 6C:box 3:bay 2, SAS, 1 TB, OK) array J physicaldrive 6C:3:3 (port 6C:box 3:bay 3, SAS, 1 TB, OK) physicaldrive 6C:3:4 (port 6C:box 3:bay 4, SAS, 1 TB, OK) array K physicaldrive 7C:3:5 (port 7C:box 3:bay 5, SAS, 1 TB, OK) physicaldrive 7C:3:6 (port 7C:box 3:bay 6, SAS, 1 TB, OK) unassigned physicaldrive 7C:3:7 (port 7C:box 3:bay 7, SAS, 1 TB, OK) physicaldrive 7C:3:8 (port 7C:box 3:bay 8, SAS, 1 TB, OK)
      Output Expected :
      data array A physicaldrive 2C:1:1 port 2C:box 1:bay 1 SAS 1 TB OK physicald +rive 2C:1:2 port 2C:box 1:bay 2 SAS 1 TB OK array B physicaldrive 2C:1:3 port 2C:box 1:bay 3 SAS 1 TB OK physicald +rive 2C:1:4 port 2C:box 1:bay 4 SAS 1 TB OK .......................................
      The Code that I has written has parsed the O/P as follows .
      #!/usr/bin/perl ############# use strict; use warnings; use Data::Dumper; my %unitMap; my $skipNext; my $cmd = "command";; open my $fd, "$cmd|" or return \%unitMap; while (my $row = <$fd>) { $row =~ /^$/ and next; $row =~ s/[,|)|(]//g; chomp $row; next if $row =~ /^Smart/g; $row =~ s/^\s+//; if( $row =~ /^unassigned/ ){ $skipNext = 2; next; } if( $skipNext ){ $skipNext--; next; } print "$row\n";
      O/P from my Code :
      data array A physicaldrive 2C:1:1 port 2C:box 1:bay 1 SAS 1 TB OK physicaldrive 2C:1:2 port 2C:box 1:bay 2 SAS 1 TB OK array B physicaldrive 2C:1:3 port 2C:box 1:bay 3 SAS 1 TB OK physicaldrive 2C:1:4 port 2C:box 1:bay 4 SAS 1 TB OK array C physicaldrive 3C:1:5 port 3C:box 1:bay 5 SAS 1 TB OK physicaldrive 3C:1:6 port 3C:box 1:bay 6 SAS 1 TB OK array D physicaldrive 3C:1:7 port 3C:box 1:bay 7 SAS 1 TB OK physicaldrive 3C:1:8 port 3C:box 1:bay 8 SAS 1 TB OK array E physicaldrive 4C:2:1 port 4C:box 2:bay 1 SAS 1 TB OK physicaldrive 4C:2:2 port 4C:box 2:bay 2 SAS 1 TB OK array F physicaldrive 4C:2:3 port 4C:box 2:bay 3 SAS 1 TB OK physicaldrive 4C:2:4 port 4C:box 2:bay 4 SAS 1 TB OK array G physicaldrive 5C:2:5 port 5C:box 2:bay 5 SAS 1 TB OK physicaldrive 5C:2:6 port 5C:box 2:bay 6 SAS 1 TB OK array H physicaldrive 5C:2:7 port 5C:box 2:bay 7 SAS 1 TB OK physicaldrive 5C:2:8 port 5C:box 2:bay 8 SAS 1 TB OK array I physicaldrive 6C:3:1 port 6C:box 3:bay 1 SAS 1 TB OK physicaldrive 6C:3:2 port 6C:box 3:bay 2 SAS 1 TB OK array J physicaldrive 6C:3:3 port 6C:box 3:bay 3 SAS 1 TB OK physicaldrive 6C:3:4 port 6C:box 3:bay 4 SAS 1 TB OK array K physicaldrive 7C:3:5 port 7C:box 3:bay 5 SAS 1 TB OK physicaldrive 7C:3:6 port 7C:box 3:bay 6 SAS 1 TB OK
        Your code is missing a semicolon at the end of this line:
        open $fd, "$cmd|"
        Also - I dont see how running the command "Command" would produce the output you show.

        I would also recommend using "my $fd", otherwise, "strict" would complain.

                "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams