Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > formating pipe delimited file

Reply
Thread Tools

formating pipe delimited file

 
 
J
Guest
Posts: n/a
 
      02-11-2004
I have a file with 40000 lines. Each line is a row of data, and the fields
are seperated by pipes ( | ). I would like to align all pipes so that the
fields will line up.

example:

field1 | 100 | 1 | | |
field2islong| | example | | 3 |

would become

field1 | 100 | 1 | | |
field2islong| | example | | 3 |


anyone have any ideas.

J

 
Reply With Quote
 
 
 
 
J. Gleixner
Guest
Posts: n/a
 
      02-11-2004
J wrote:
> I have a file with 40000 lines. Each line is a row of data, and the fields
> are seperated by pipes ( | ). I would like to align all pipes so that the
> fields will line up.
>
> example:
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
> would become
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
>
> anyone have any ideas.
>
> J
>


split each line, find the maximun length for each column, then use
printf with the max length of each column.
 
Reply With Quote
 
 
 
 
Bob Walton
Guest
Posts: n/a
 
      02-11-2004
J wrote:

> I have a file with 40000 lines. Each line is a row of data, and the fields
> are seperated by pipes ( | ). I would like to align all pipes so that the
> fields will line up.

....
> J


Do you know any information on field lengths up front? If not, you'll
have to pass through your data once to determine the maximum length of
each field, then pass through it again to output it. The actual program
to do that is trivial. The "x" operator would be useful in it.

You will have to decide if you want to read the entire file to memory
the first time through (I don't know what 40000 lines translates to in
bytes, or what that number of bytes means to your computer system), or
whether the file should be read twice.

--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl

 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      02-11-2004

J <> wrote:
> I have a file with 40000 lines. Each line is a row of data, and the fields
> are seperated by pipes ( | ). I would like to align all pipes so that the
> fields will line up.
>
> example:
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
> would become
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
>
> anyone have any ideas.


(untested)

use Fcntl qw/:seek/;

{
open my $FILE, '<', $file or die "can't open $file: $!";
my @lengths;

while (<$FILE>) {
my @f = split /\|/;
for (0..$#f) {
$lengths[$_] < length $f[$_]
and $lengths[$_] = length $f[$_];
}
}

my $fmt = join '|', map "%-$_s", @lengths;

seek $FILE, 0, SEEK_SET;

{
open my $OUT, '>', "$file.new"
or die "can't create $file.new: $!";

local $\ = "\n";
# or maybe "|\n", if the last field is really null

while (<$FILE>) {
print $OUT sprintf $fmt => split /\|/;
}
}
}

rename "$file.new", $file or die "can't overwrite $file: $!";

--
Although few may originate a policy, we are all able to judge it.
- Pericles of Athens, c.430 B.C.

 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      02-12-2004
J wrote:
>
> I have a file with 40000 lines. Each line is a row of data, and the fields
> are seperated by pipes ( | ). I would like to align all pipes so that the
> fields will line up.
>
> example:
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
> would become
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
> anyone have any ideas.


Something like this should work:

#!/usr/bin/perl
use warnings;
use strict;

( $^I, @ARGV ) = ( '.bak', 'yourfile.txt' );

my @lens = map length, split /\|/, <>, -1;
while ( <> ) {
chomp;
my $i = -1;
$lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_, -1;
}
@ARGV = $ARGV;
while ( <> ) {
chomp;
my $i;
print join( '|', map sprintf( '%-*s', $lens[ $i++ ], $_ ), split /\|/, $_, -1 ), "\n";
}

__END__



John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      02-12-2004
J <> wrote in comp.lang.perl.misc:
> I have a file with 40000 lines. Each line is a row of data, and the fields
> are seperated by pipes ( | ). I would like to align all pipes so that the
> fields will line up.
>
> example:
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |
>
> would become
>
> field1 | 100 | 1 | | |
> field2islong| | example | | 3 |


Ah... an alignment problem. That's an occasion to plug Text::Table

use Text::Table;

# Define a table with 5 columns, untitled, with "|" as column separators
my $tb = Text::Table->new( ('', \ '|') x 5);

# Fill in the data lines
$tb->add( split /\|/) while <DATA>;

# print the re-formatted lines
print $tb;

__DATA__
field1 | 100 | 1 | | |
field2islong| | example | | 3 |


Anno
 
Reply With Quote
 
J
Guest
Posts: n/a
 
      02-13-2004
On Thu, 12 Feb 2004 1:22:28 -0500, John W. Krahn wrote
(in message <>):

> J wrote:
>
> Something like this should work:
>
> #!/usr/bin/perl
> use warnings;
> use strict;
>
> ( $^I, @ARGV ) = ( '.bak', 'yourfile.txt' );
>
> my @lens = map length, split /\|/, <>, -1;
> while ( <> ) {
> chomp;
> my $i = -1;
> $lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,
> -1;
> }
> @ARGV = $ARGV;
> while ( <> ) {
> chomp;
> my $i;
> print join( '|', map sprintf( '%-*s', $lens[ $i++ ], $_ ), split /\|/,
> $_, -1 ), "\n";
> }
>
> __END__



I'm having a hard time understand this line of code
$lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,-1

Could some one explain this line of code.

John

 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      02-13-2004
J wrote:
>
> On Thu, 12 Feb 2004 1:22:28 -0500, John W. Krahn wrote
> (in message <>):
>
> > J wrote:
> >
> > Something like this should work:
> >
> > #!/usr/bin/perl
> > use warnings;
> > use strict;
> >
> > ( $^I, @ARGV ) = ( '.bak', 'yourfile.txt' );
> >
> > my @lens = map length, split /\|/, <>, -1;
> > while ( <> ) {
> > chomp;
> > my $i = -1;
> > $lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,
> > -1;
> > }
> > @ARGV = $ARGV;
> > while ( <> ) {
> > chomp;
> > my $i;
> > print join( '|', map sprintf( '%-*s', $lens[ $i++ ], $_ ), split /\|/,
> > $_, -1 ), "\n";
> > }
> >
> > __END__

>
> I'm having a hard time understand this line of code
> $lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,-1
>
> Could some one explain this line of code.


Sure, to put it more verbosely:

# set $index to -1 because we pre-increment it in the loop
my $index = -1;

# split the line in $_ using the pipe '|' character
# third argument is -1 to get trailing empty fields
for my $field ( split /\|/, $_, -1 ) {

my $length = length $field;

++$index;

if ( $lens[ $index ] < $length ) {

# store $length in the array @lens if it is
# greater than the previous value in @lens
$lens[ $index ] = $length;
}
}



John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
J
Guest
Posts: n/a
 
      02-16-2004
On Fri, 13 Feb 2004 0:11:50 -0500, John W. Krahn wrote
(in message <>):

> J wrote:
>>
>> On Thu, 12 Feb 2004 1:22:28 -0500, John W. Krahn wrote
>> (in message <>):
>>
>>> J wrote:
>>>
>>> Something like this should work:
>>>
>>> #!/usr/bin/perl
>>> use warnings;
>>> use strict;
>>>
>>> ( $^I, @ARGV ) = ( '.bak', 'yourfile.txt' );
>>>
>>> my @lens = map length, split /\|/, <>, -1;
>>> while ( <> ) {
>>> chomp;
>>> my $i = -1;
>>> $lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,
>>> -1;
>>> }
>>> @ARGV = $ARGV;
>>> while ( <> ) {
>>> chomp;
>>> my $i;
>>> print join( '|', map sprintf( '%-*s', $lens[ $i++ ], $_ ), split /\|/,
>>> $_, -1 ), "\n";
>>> }
>>>
>>> __END__

>>
>> I'm having a hard time understand this line of code
>> $lens[ ++$i ] < $_ and $lens[ $i ] = $_ for map length, split /\|/, $_,-1
>>
>> Could some one explain this line of code.

>
> Sure, to put it more verbosely:
>
> # set $index to -1 because we pre-increment it in the loop
> my $index = -1;
>
> # split the line in $_ using the pipe '|' character
> # third argument is -1 to get trailing empty fields
> for my $field ( split /\|/, $_, -1 ) {
>
> my $length = length $field;
>
> ++$index;
>
> if ( $lens[ $index ] < $length ) {
>
> # store $length in the array @lens if it is
> # greater than the previous value in @lens
> $lens[ $index ] = $length;
> }
> }
>
>
>
> John
>


I understand a little bit better. That is the hardest thing about perl for
me, is understanding all the shortcut codes.

Thanks for explaining stuff to me.

J

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Help "joining" two files delimited with pipe character ("|") Miki Tebeka Python 0 12-05-2012 06:17 PM
converting pipe delimited file to fixed width digz Python 5 03-19-2009 05:40 PM
DataReader to pipe delimited file question Elmo Watson ASP .Net 1 01-25-2008 12:17 AM
convert non-delimited to delimited RyanL Python 6 08-28-2007 12:06 AM
Can someone point me in the right direction? Pipe Delimited Files& Hashes... Samantha Ruby 7 03-07-2007 04:32 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57