• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 369
  • Last Modified:

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

I have the following data record below that starts with __Data__. Within this data record, I would like to create another data record using the __Data__ as the field separator.

Here's an example data record

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

I would like the above output to be...

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

__Data__
@test_scsi_2
scatter-gatter test
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds


Start code
-------------
#!/usr/bin/perl

use warnings;
use strict;

$/='__Data__';


    open 'FH','<',"/home/data_records";
    while(<FH>)
   {
       if(/(\@[^\n]*)(.*)(test_scsi[^\n]*)(.*)(test_scsi[^\n]*)(.*)/ms)
       {
         print $1,$2,$3,$4,"\n","__Data__","\@",$5,$6;
       }
    }

The above is far from working but its a limitation of my idea. But if there is a better way to do it, please let me know.
0
areyouready344
Asked:
areyouready344
  • 5
  • 2
1 Solution
 
Fairlight2cxCommented:
#!/usr/bin/perl -w

use strict;

my $count = 0;
open(FH,"<data");
while (my $line = <FH>) {
     chomp($line);
     if ($line =~ /^\@test_scsi/) {
          print("\n__Data__\n") unless $line =~ /^__Data__\n$/ or $count == 0;
          $count++;
     }
     print("$line\n");
}
exit;
0
 
areyouready344Author Commented:
Thanks but did not work, the output came out like this....

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


It should come out like this:

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

__Data__
@test_scsi_2
scatter-gatter test
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds
0
 
wilcoxonCommented:
This will do it...
#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

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

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

Open in new window

0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
areyouready344Author Commented:
Once again, thanks Wilcoxon.

One question, how can I make the (test_scsi.*) more flexible for additional OR options.
For example, I tried the following but giving the same results.

((test_scsi|test_sas|test_sata).*)

total code...

#!/usr/bin/perl

use strict;
use warnings;

$/='__Data__';

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

sub split_block {
    my ($txt) = @_;
    return $txt unless ($txt =~ m{^(\@test_scsi.*?\n)((test_scsi|test_sas|test_sata).*)$}ms);
    return "$1\n__Data__\n" . split_block('@'.$2);
}
0
 
areyouready344Author Commented:
Oops, For example, I tried the following but giving the same results.
Correct, For example, I tried the following but not giving me the same results as the original code.
0
 
areyouready344Author Commented:
One minor problem is spotted, first data record line does not line up correctly as in -->(__Data__@test_scsi_1) should be

__Data__
@test_scsi_1

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

__Data__
@test_scsi_2
scatter-gatter test
windows (vista)
1.  fskdjfklsjdfksjkfdjskldjfklsjfkdlsjklfjsdkljflkds
2.  djfkldsjfklsjdklsjfkldjsklfjdklsjfkldsjfklsjdkljfsl
windows (vists)
fjksjfdklsjfkldsjklfjdsljfklsklfs
djflsdjkflsjdkflsjfkldsjklfjsklfds
0
 
wilcoxonCommented:
This should do it.  You can just change the $anchor definition to alter what text is considered the start of a __Data__ section.  This also fixes the first line issue.
#!/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
 
areyouready344Author Commented:
Everything is working correctly, thanks. But I made a mistake on the request. I'll close this ticket out and open another one.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now