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.