简体   繁体   中英

Split file contents into 2 arrays based on a key word

I have a file which has something like

line1
line2
line3
line4
.endm
line5
line6
line7
line8
.endm

I want to split this file at .endm and put the contents in 2 different arrays. Output would be

@array1=(line1,line2,line3,line4);
@array2=(line4,line6,line7,line8);

I tried using

@array = split(".endm",my_file.txt);
print("Array1 = $array[1]\nArray2 = $array[2]\n);

But this just prints out the line number of the last .endm

I also tried something like

#! /usr/intel/bin/perl -w
use strict;

my $count=0;
open(my $fh, "<", "a.txt")|| die "can't open UTF-8 encoded filename: $!";
my @lines = <$fh>;
my @array;

LOOP: foreach my $line (@lines) {
    chomp ($line);
    $count = $count+1;
    push (@array,$line);  
    if ($line =~ m/.endm/) {
        pop (@array);
        last LOOP;
    }
}
print("Array : @array\n");
close $fh;

This one prints @array=(line1,line2,line3,line4); But I still need the other 4 lines so that I can put it in a different array

So how do I go about splitting a file based on some keyword?

If you have a fixed string as field separator, you can set the built-in variable $/ -- the input record separator -- to change how Perl's readline() function reads lines.

perl -MData::Dumper -we '$/=".endm\n"; chomp(@a = <>); 
      @a = map [ split /\n/ ], @a; print Dumper \@a;' file.txt

This will read the file in two chunks, effectively splitting on .endm\\n . Note that chomp removes the value of $/ from the end of a string. The map statement here simply splits the input on newline and puts it in an array ref. The resulting array is two-dimensional, as seen in the Data::Dumper output:

Output:

$VAR1 = [
          [
            'line1',
            'line2',
            'line3',
            'line4'
          ],
          [
            'line5',
            'line6',
            'line7',
            'line8'
          ]
        ];

The full version looks like this:

use strict;
use warnings;
use Data::Dumper;

$/ = ".endm\n";
chomp(my @a = <>);
@a = map [split /\n/], @a;
print Dumper \@a;

I'd keep it simple and do it this way:

my (@array1,@array2);
while ($_ = <>) { chomp; last if $_ eq '.endm'; push @array1, $_ }
while ($_ = <>) { chomp; last if $_ eq '.endm'; push @array2, $_ }
#!/usr/bin/perl 
use strict;
use warnings;
use Data::Dumper;

open my $fh, '<', 'data.txt' or die "can't open data.txt: $!";

my @array;

$/ = ".endm";

while (<$fh>){
    s/\.endm$//;
    push @array, [split];
}

print Dumper(@array);

#output
$VAR1 = [
         'line1',
         'line2',
         'line3',
         'line4'
        ];
$VAR2 = [
         'line5',
         'line6',
         'line7',
         'line8'
        ];

If the file is small in size, this will work.

#!/usr/bin/perl 

use strict;
use warnings;

open(FILE,"input.txt");
my @lines =<FILE>;                 # Reads all lines of the file into an array
my $line  = join('',@lines);       # Join all lines together
my @temp = split(/.endm/,$line);   # Split the line using the keyword
my @array1=split(/\n/,$temp[0]);   # Splits line back 
my @array2=split(/\n/,$temp[1]);   # Splits line back

print @array1;
print "\n";
print @array2;

close(FILE);
use 5.10.0;
use strict;
use warnings;

open( my $fh, '<', 'a.txt' ) or die "can't open filename: $!";

my @arrays;
my $array = [];

while (<$fh>) {
    chomp;
    if (/^\.endm$/) {
        push @arrays, $array;
        $array = [];
        next;
    }
    push @$array, $_;
}

local $, = ",";
say @$_ for @arrays;

$array = [] is unnecessary but improve readability. And output:

line1,line2,line3,line4
line5,line6,line7,line8

You don't bother reading docs or tutorials before you write your code, do you? Split splits string to array, not file to lines.

open INPUT,"<my_file.txt" or die "no such file";
my @array1;
my @array2;
my $ref = \@array1;
while ( my $line = <INPUT> ) {
  chomp($line);
  if ( $line eq ".endm" ) {
    $ref = \@array2;
  } else {
    push(@$ref,$line);
  }
}
print $_ . " " foreach @array1;
print "\n";
print $_ . " " foreach @array2;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM