Reputation: 475
I am parsing through a file.
The file format is like this:
Column1 Column2 Column3 Column4 Column5
1 2 3 4 5
6 7 8 9
10 11 12 14
15 16 17 18
Some of the Column's are empty. So I am reading two files having same format as above and merging both files and adding the "|" between each column so it should look like this:
Column1 | Column2 | Column3 | Column4 | Column5
1 | 2 | 3 | 4 | 5
6 | 7 | | 8 | 9
10 | 11 | 12 | | 14
| 15 | 16 | 17 | 18
But I'm getting like this. The spaces in columns are removed.
Column1 | Column2 | Column3 | Column4 | Column5
1 | 2 | 3 | 4 | 5
6 | 7 | 8 | 9
10 | 11 | 12 | 14
15 | 16 | 17 | 18
Code part:
while(<FH>){
my @lines =split ' ',$_;
say (join '|',@lines);
}
I know this is happening because I am splitting with space delimiter. Can anyone tell me how to get the desired output?
Upvotes: 3
Views: 117
Reputation: 1832
If you don't need to parse the data to do anything with, just reformat it, you can use a regex substitution to add in the vertical bar characters.
This code will add |
after every 9 characters. This assumes that your data is fixed width columns. The \K
assertion means to keep (get it?) all of the leftward matched text and not replace it with the substitution text. So in effect it allows you to set the point where text from the right side of the s///
will be placed. The /m
option tells Perl that this is a multi-line string. The (?!$)
assertion means "not at the end of the line" so that we don't insert anything after the final column.
I did it with all of the text in a single variable but you could do it line by line.
If the columns are variable width you can still do it with a regex but it gets more complicated. unpack/sprintf
may well be simpler in that case.
$s = '
Column1 Column2 Column3 Column4 Column5
1 2 3 4 5
6 7 8 9
10 11 12 14
15 16 17 18
';
$s =~ s/.{9}(?!$)\K/| /gm;
print $s;
Column1 | Column2 | Column3 | Column4 | Column5
1 | 2 | 3 | 4 | 5
6 | 7 | | 8 | 9
10 | 11 | 12 | | 14
| 15 | 16 | 17 | 18
More info perlre.
Thanks.
Upvotes: 0
Reputation: 62236
You can use unpack to parse fixed-width data. The A9
in the template assumes your columns are 9 characters wide. You can use sprintf to space the data out again into columns of the original width.
use warnings;
use strict;
while (<DATA>) {
chomp;
printf "%s\n", join '| ', map { sprintf '%-8s', $_ } unpack 'A9' x 5, $_;
}
__DATA__
Column1 Column2 Column3 Column4 Column5
1 2 3 4 5
6 7 8 9
10 11 12 14
15 16 17 18
This prints:
Column1 | Column2 | Column3 | Column4 | Column5
1 | 2 | 3 | 4 | 5
6 | 7 | | 8 | 9
10 | 11 | 12 | | 14
| 15 | 16 | 17 | 18
Upvotes: 8