tim
tim

Reputation: 45

Join element in an array and separate with space

I want to join the first to 16th word and 17th to 31st, etc in an array with space to one line but do not know why the code does not work. Hope to get help here.Thanks

my @file = <FILE>;
for ( $i=0; $i<=$#file; $i+=16 ){
    my $string = join ( " ", @file[$i..$i+15] );
    print FILE1 "$string\n";
}

Below is part of my file.

1
2
3
...

What i wan to print is

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17 18 19 20 21....

Upvotes: 0

Views: 1059

Answers (4)

Kosh
Kosh

Reputation: 18444

Assuming that you have FILE and FILE1 descriptors open, try:

$.%16?s!\s+! !:1 and print FILE1 $_ while <FILE>;

Upvotes: 1

mkHun
mkHun

Reputation: 5921

Suppose if you want to read it from file, don't store the whole file into an array. Instead loop through line by line. And check the line number with $. special variable.

use warnings;
use strict;
open my $fh,"<","input.txt";
my $line;
while (<$fh>)
{
    chomp;

    $line.= $_." ";

    print "$line\n" and $line="" if($. % 16 == 0);

    END{ print "$line\n";};
}

Or this also will work

use warnings;
use strict;
open my $wh,"<","input.txt";
my $line;
foreach (;;)
{
    my $data = join " ",(map { my $m=<$wh> || ""; chomp($m); $m} (0..15));

    last if ($data =~m/^\s+$/);

    print $data,"\n";   

}   

Upvotes: 2

Sobrique
Sobrique

Reputation: 53508

I wouldn't do it the way you've done it.

Instead I would:

open ( my $input, '<', "your_file_name" ) or die $!;
chomp ( my @file = <$input> ); 
print join (" ",splice (@file, 0, 15)),"\n" while @file;

Note - I've used a lexical file handle with a 3 argument open, because that's better style.

splice removes the first 16 elements from @file each iteration, and continues until @file is empty.

Upvotes: 5

simbabque
simbabque

Reputation: 54381

Your lines have newlines attached to them. Remove them with chomp. Then loop over the array, remove 16 items and print them.

my @file = <FILE>;
chomp @file;

while (@file) {
    my @temp;
INNER: for ( 0 .. 15 ) {
        push @temp, shift @file || last INNER; # not or
    }
    print join( q{ }, @temp ), "\n";
}

This is the long implementation of the splice solution Sobrique suggested in the comments. It's does the same thing, just way more verbose.


This is the old answer before the edit:

If you only want the first 16, this is way more effective.

my $string = join q{ }, map { <FILE>; chomp; $_ } 1 .. 16;

This reads 16 lines and chomp each of them, then joins.

You might also want to use lexical file handles $fh instead of the GLOB FILE.

open my $fh, '<', $path_to_file or die $!;

Upvotes: 2

Related Questions