For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > December 2007 > Ragged Hierarchy









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Ragged Hierarchy
Banker123

2007-12-21, 4:01 am

I have a text file with a ragged hierarchy as shown below, I would
like to structure the data in a different format (also shown below)
please help. Also the data below is just an example the actual data
file is much larger and the hierarchy has 10 levels the lowest level
"Employee" could be stored anywhere wtihin the 10 levels depeding
upon
the business units structure. I have not used Perl in about 6 months
but
if memory serves me correctly Perl is the perfect tool for the job.

Original
Company Business Unit1 Employee1
Company Business Unit1 Business Unit2 Employee2


New
Employee1 Company Business Unit1
Employee2 Company Business Unit1 Business Unit2


Tom Phoenix

2007-12-21, 4:01 am

On 12/20/07, banker123 <bradbrockman@yahoo.com> wrote:

> I have a text file with a ragged hierarchy as shown below, I would
> like to structure the data in a different format (also shown below)
> please help.


It sounds as if you want to read a text file, build a Perl data
structure in memory, perhaps modify parts of the structure, then write
the data out to another file. Perl is good at this sort of thing.

How far have you gotten on your own? Do you know how to read your data
into a Perl data structure, for example? If you can post the code that
you've written, someone may have some suggestions for how to improve
it.

Cheers!

--Tom Phoenix
Stonehenge Perl Training
John W . Krahn

2007-12-21, 4:01 am

On Thursday 20 December 2007 07:49, banker123 wrote:
>
> I have a text file with a ragged hierarchy as shown below, I would
> like to structure the data in a different format (also shown below)
> please help. Also the data below is just an example the actual data
> file is much larger and the hierarchy has 10 levels the lowest level
> "Employee" could be stored anywhere wtihin the 10 levels depeding
> upon the business units structure. I have not used Perl in about 6
> months but if memory serves me correctly Perl is the perfect tool for
> the job.
>
> Original
> Company Business Unit1 Employee1
> Company Business Unit1 Business Unit2 Employee2
>
>
> New
> Employee1 Company Business Unit1
> Employee2 Company Business Unit1 Business Unit2



$ echo "Company Business Unit1 Employee1
Company Business Unit1 Business Unit2 Employee2" |\
perl -lne'
my ( $co, @data ) = split /\s{2,}/;
my ( $bu, $empl ) = splice @data, -2;
printf q[%-14s%-12s] . ( q[%-19s] x @data ) . qq[%s\n], $empl, $co,
@data, $bu;
'
Employee1 Company Business Unit1
Employee2 Company Business Unit1 Business Unit2




John
--
use Perl;
program
fulfillment
Michael Wang

2007-12-21, 4:01 am

On 12/20/07, banker123 <bradbrockman@yahoo.com> wrote:
>
> I have a text file with a ragged hierarchy as shown below, I would
> like to structure the data in a different format (also shown below)
> please help. Also the data below is just an example the actual data
> file is much larger and the hierarchy has 10 levels the lowest level
> "Employee" could be stored anywhere wtihin the 10 levels depeding
> upon
> the business units structure. I have not used Perl in about 6 months
> but
> if memory serves me correctly Perl is the perfect tool for the job.
>
> Original
> Company Business Unit1 Employee1
> Company Business Unit1 Business Unit2 Employee2
>
>
> New
> Employee1 Company Business Unit1
> Employee2 Company Business Unit1 Business Unit2
>
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> http://learn.perl.org/



if you only need re-organize company and employee


use strict;
use warnings;

while(<DATA> ){

chomp;
my @line = split/\s{5}/;
print join (" ", @line[-1, 0, 1.. $#line -1]), "\n";
}
__DATA__
Company Business Unit1 Employee1
Company Business Unit1 Business Unit2 Employee2
Company Business Unit1 Business Unit2 Business
Unit3 Employee3

Banker123

2007-12-21, 4:01 am

I have two started the first is my attempt to read the file into an
array, the second is processing each variable. I am unsure how to
identify the last variable in a variable length line of data.

open (input, 'c:\organization.txt') or die "Cannot open file: $!";
@data=<input>;

foreach $line(@data){
print $line;
}

open ('input', 'c:\organization.txt') or die "Cannot open file: $!";
open ('output', '>C:/out.txt') or die "Cannot open file: $!";

while (<input> ) {
my
($v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v1
0,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v1
8,$v19,$v20,$v21,$v22,$v23,$v24)
= split (/,/);
print output
" $v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v10
,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v18
,$v19,$v20,$v21,$v22,$v23,$v24\n";
}

Banker123

2007-12-21, 4:01 am

Here is what I have:

open ('input', 'C:/Organization.txt') or die "Cannot open file: $!";
open ('output', '>C:/out.txt') or die "Cannot open file: $!";

while (<input> ) {
my
($v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v1
0,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v1
8,$v19,$v20,$v21,$v22,$v23,$v24)
= split (/,/);
print output
" $v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v10
,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v18
,$v19,$v20,$v21,$v22,$v23,$v24\n";
}

This reads the input file one line at a time, seperates the variables
using the comma as the delimiter, and outputs the variables to a file
called out.txt. The challenge is that the file is a structured
hierarchy as explained in the original post, I do not know when the
lowest level (employee, and this an employees name) will occur in the
hierarhcy and I need to get this lowest level value as the first
variable in my out.txt file.

Tom Phoenix

2007-12-21, 4:01 am

On 12/20/07, banker123 <bradbrockman@yahoo.com> wrote:

> I have two started the first is my attempt to read the file into an
> array, the second is processing each variable. I am unsure how to
> identify the last variable in a variable length line of data.
>
> open (input, 'c:\organization.txt') or die "Cannot open file: $!";


It's generally good practice to use all caps for filehandle names, or
to use lexical variables. Also, for a number of reasons, it's better
to use forward slashes instead of backslashes in literal filenames. So
I'd probably re-write that code something like this, and change the
rest of the code accordingly:

open my $input, "c:/organization.txt" or die "Can't open file: $!";

> open ('input', 'c:\organization.txt') or die "Cannot open file: $!";
> open ('output', '>C:/out.txt') or die "Cannot open file: $!";


I'm not sure what you're trying to do here; didn't you already open
your input filehandle? But using strings as filehandle names like that
is discouraged.

> my
> ($v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v1
0,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v1
8,$v19,$v20,$v21,$v22,$v23,$v24)
> = split (/,/);


Ouch! Using many numbered variables is a warning sign that a data
structure is needed. In this case, an array could make your life much
simpler. After using split() into an array, the problem of identifying
the last element's index is easy; it's the last valid index of the
array.

my @v = split /,/, $_;
my $last_elem_index = $#v;

Does that get you closer to a solution? Good luck with it!

--Tom Phoenix
Stonehenge Perl Training
Banker123

2007-12-21, 7:02 pm

Still stuck, OK I read the data file into an array split the variables
using the comma as the delimiter. How do I find the last elemennt in
each of the lines as explained in the original post?

Gunnar Hjalmarsson

2007-12-21, 7:02 pm

banker123 wrote:
> Tom Phoenix wrote:
>
> Still stuck, OK I read the data file into an array split the variables
> using the comma as the delimiter. How do I find the last elemennt in
> each of the lines as explained in the original post?


Don't you read the answers you get?

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Banker123

2007-12-21, 7:02 pm

Some mild progress here is what I have so far. Couple of questions:

1. This only processes the first record in the file, the file has many
records and I would like to process each record.
2. My array has empty elements, how do I remove empty or blank
elements?
3. When I print the array the first element is on row 1 and the
remaining elements are on row 2, how do I print on 1 row?

open INPUT, "c:/organization.txt" or die "Can't open file: $!";
open OUTPUT, ">c:/out.txt" or die "Can't open file: $!";

$data=<INPUT>;
@array=split(',',$data);
@slicedata=@array[-1,-2,-3,-4,-5,-6,-7];
print OUTPUT "@slicedata";

John W . Krahn

2007-12-21, 7:02 pm

On Friday 21 December 2007 11:01, banker123 wrote:
> Some mild progress here is what I have so far. Couple of questions:
>
> 1. This only processes the first record in the file, the file has
> many records and I would like to process each record.
> 2. My array has empty elements, how do I remove empty or blank
> elements?
> 3. When I print the array the first element is on row 1 and the
> remaining elements are on row 2, how do I print on 1 row?
>
> open INPUT, "c:/organization.txt" or die "Can't open file: $!";
> open OUTPUT, ">c:/out.txt" or die "Can't open file: $!";
>
> $data=<INPUT>;
> @array=split(',',$data);
> @slicedata=@array[-1,-2,-3,-4,-5,-6,-7];
> print OUTPUT "@slicedata";


Or simply:

my @slicedata = ( reverse split /,/, <INPUT> )[ 0 .. 6 ];
print OUTPUT "@slicedata";


John
--
use Perl;
program
fulfillment
Tom Phoenix

2007-12-21, 7:02 pm

On Dec 21, 2007 11:01 AM, banker123 <bradbrockman@yahoo.com> wrote:

> 1. This only processes the first record in the file, the file has many
> records and I would like to process each record.


It sounds as if you want to wrap what you have in a loop. Perhaps you
want to do something like this:

while (my $data = <INPUT> ) {
# existing code
}

> 2. My array has empty elements, how do I remove empty or blank
> elements?


With grep(), probably. It's documented in the perlfunc manpage.

> 3. When I print the array the first element is on row 1 and the
> remaining elements are on row 2, how do I print on 1 row?


You probably need chomp(), to get rid of the unwanted newline on the
input data string. Put it inside the while loop:

chomp($data);

Of course, you'll have to add code to output newline characters where
you do want line breaks.

> @slicedata=@array[-1,-2,-3,-4,-5,-6,-7];


Maybe you want reverse()?

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com