Solved

How to create data records out of data records using Perl - Part2?

Posted on 2011-03-16
10
263 Views
Last Modified: 2012-05-11
Building on Wilcoxon code, how can I make a data record split on the a windows types. I want to run a report based on the windows type being tested.

For example,

@test_scsi_1
memory test
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds

I would like to output to be:

__Data__
@test_scsi_1
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj

__Data__
@test_scsi_1
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds


To sum up, within the first data record, the test was performed under windows vista and xp both under test_scsi_1. Now I wanna split the record based on the window type but under the same test (test_scsi_1)
#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

my $anchor = '(?:test_scsi|test_sas|test_sata)';

open 'FH','<',"/home/data_records";
while (<FH>) {
    print split_block($_), "\n";
}

sub split_block {
    my ($txt) = @_;
    return $txt unless ($txt =~ m{^(\@$anchor.*?\n)($anchor.*)$}ms);
    return "$1\n__Data__\n" . split_block('@'.$2);
}

Open in new window

0
Comment
Question by:areyouready344
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
10 Comments
 
LVL 26

Expert Comment

by:wilcoxon
ID: 35157771
Do you still want it to split __Data__ blocks at test_scsi entries as well?
0
 

Author Comment

by:areyouready344
ID: 35158003
Thanks Wilcoxon, I worked out the answer.

my ($txt) = @_;
my $test_name;

    foreach (@_)
    {
     if(/^(\@.*)/m)
     {
      $test_name = $1;
     }
    }

    return $txt unless ($txt =~ m{^(\@.*?\n)($anchor.*)$}ms);
    return "$1\n__Data__\n" . "$test_name\n" . split_block($2);
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 35158045
This should handle it either way...
#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

my $anchor = '(?:test_scsi|test_sas|test_sata)';

open 'FH','<',"/home/data_records";
while (<FH>) {
    next if m{^[\s\n]*__Data__\n*$};
    print "__Data__\n", split_block($_), "\n";
}

sub split_block {
    my ($txt) = @_;
    $txt =~ s{[\s\n]*__Data__\n*$}{}ms;
    return split_win($txt) unless ($txt =~ m{^(\@$anchor.*?\n)($anchor.*)$}ms);
    return split_win($1) . "\n__Data__\n" . split_block('@'.$2);
}

sub split_win {
    my ($txt) = @_;
    return $txt unless ($txt =~ m{^(\@$anchor.*?\n)(windows.*?\nwindows.*)$}ms);
    my ($hdr, $rest) = ($1, $2);
    my %sec;
    while ($txt =~ m{^(windows\s+\((\w+)\).*?\n)(?=windows|$)}msgc) {
        $sec{$2} = [] unless $sec{$2};
        push @{$sec{$2}}, $1;
    }
    return join "\n__Data__\n", map { join '', $hdr, @{$sec{$_}} } sort keys %sec;
}

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 26

Expert Comment

by:wilcoxon
ID: 35158144
I see you posted your own solution.  Are you sure that works?  I put your code in split_block and don't get the results you said you wanted.  Did you make any further changes to the original code you posted besides that block in your comment?

Also, in your sample data, you have vista typoed as vists in one place.
0
 

Author Comment

by:areyouready344
ID: 35166098
I can't believe your code is working as I requested, you even added the subtest name in split data records. Now I need to run it live.
0
 

Author Comment

by:areyouready344
ID: 35166220
One fault on my request, can you make windows (vista, xp) more flexible to include other Operating Systems. I forgot to mention, these are VMs (virtual machines) may include MAC, linux, along with the different versions of windows. Adding an anchor would be great like you did for here -->> $anchor = '(?:test_scsi|test_sas|test_sata)';


This example includes additional OSs and may includes the type of application,

__Data__
@test_scsi_1
memory test
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj
linux
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds
MAC
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds
0
 

Author Comment

by:areyouready344
ID: 35166590
I was afraid that if the data record did not require a split you might change it in some but you did not, great...

For example, output of the record below did not change using your code because no split is required, thanks Wilcoxon for keeping that in mind...

__Data__
@test_scsi_1
memory test
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 35167233
This should do what you want.  Just update the $os regex.
#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

my $anchor = '(?:test_scsi|test_sas|test_sata)';
my $os = '(?:windows\s+\(\w+\)|MAC|linux)';

open 'FH','<',"/home/data_records";
while (<FH>) {
    next if m{^[\s\n]*__Data__\n*$};
    print "__Data__\n", split_block($_), "\n";
}

sub split_block {
    my ($txt) = @_;
    $txt =~ s{[\s\n]*__Data__\n*$}{}ms;
    return split_win($txt) unless ($txt =~ m{^(\@$anchor.*?\n)($anchor.*)$}ms);
    return split_win($1) . "\n__Data__\n" . split_block('@'.$2);
}

sub split_win {
    my ($txt) = @_;
    return $txt unless ($txt =~ m{^(\@$anchor.*?\n)($os.*?\n$os.*)$}ms);
    my ($hdr, $rest) = ($1, $2);
    my %sec;
    while ($txt =~ m{^(($os).*?\n)(?=$os|$)}msgc) {
        $sec{$2} = [] unless $sec{$2};
        push @{$sec{$2}}, $1;
    }
    return join "\n__Data__\n", map { join '', $hdr, @{$sec{$_}} } sort keys %sec;
}

Open in new window

0
 

Author Comment

by:areyouready344
ID: 35193789
Wilcoxon, the latest code works as request but with a few issues on my end:

Issue 1

I couldn't find in the code to allow the same OS to run within the same Data Record. In order words, I may run Windows XP OS twice within the same data record but on different hardware types.

Can you make the code split when having same OS type within the same data record...

For example,

__Data__
@test_scsi_1
memory test
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vista)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds


__Data__
@test_scsi_1
memory test
windows (xp)
1.  ddkddlakldjkla;djkfla;jdlafklda;fkla;dkdkslsls
2.  dkskdslfjklsjfkdsjkldjskldjflksjdfklsjfkdlsjkflds
3.  dhskhdksfdsfjdskljflksjfkdlsjkfldjksldjklfsjkldsfj

__Data__
@test_scsi_1
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl

__Data__
@test_scsi_1
windows (vista)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds


Issue 2:

Can you remove the sorting. I its causing the output data to cut off and not needed because I will sort by the test name of the data record
0
 
LVL 26

Accepted Solution

by:
wilcoxon earned 500 total points
ID: 35216120
I think this should do what you want (typed in and untested)...
#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

my $anchor = '(?:test_scsi|test_sas|test_sata)';
my $os = '(?:windows\s+\(\w+\)|MAC|linux)';

open 'FH','<',"/home/data_records";
while (<FH>) {
    next if m{^[\s\n]*__Data__\n*$};
    print "__Data__\n", split_block($_), "\n";
}

sub split_block {
    my ($txt) = @_;
    $txt =~ s{[\s\n]*__Data__\n*$}{}ms;
    return split_win($txt) unless ($txt =~ m{^(\@$anchor.*?\n)($anchor.*)$}ms);
    return split_win($1) . "\n__Data__\n" . split_block('@'.$2);
}

sub split_win {
    my ($txt) = @_;
    return $txt unless ($txt =~ m{^(\@$anchor.*?\n)($os.*?\n$os.*)$}ms);
    my ($hdr, $rest) = ($1, $2);
    my @sec;
    while ($txt =~ m{^($os.*?\n)(?=$os|$)}msgc) {
	push @sec, $1;
    }
    return join "\n__Data__\n", map { join '', $hdr, $_ } @sec;
}

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question