Solved

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

Posted on 2011-03-16
10
258 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
  • 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
 
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
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…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

707 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now