Perl script to parse output and print it comma separated


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Perl script to parse output and print it comma separated
# 1  
Old 03-18-2011
Perl script to parse output and print it comma separated

I need to arrange output of SQL query into a comma separated format and I'm struggling with processing the output...

The output is something like this:

Code:
<Attribute1 name><x amount of white spaces><Atribute value>
<Attribute2 name><x amount of white spaces><Atribute value>
<Attribute3 name><x amount of white spaces><Atribute value>
<Attribute4 name><x amount of white spaces><Atribute value>
<Attribute5 name><x amount of white spaces><Atribute value>

- There are always 5 Attribute/Value pairs that makes one record.
- The Attribute names are not always in same order.

So it could be(example where I would have only two records 5 lines(A,B,C,D,E) each):

Code:
A   1
B   2
C  3
D   4
E  5
B  4
C    3
A  5
E  1
D  2

I would need to parse this output into the following format:
A,B,C,D,E
A,B,C,D,E
....
but using only the value, so the above 2 records would be printed as:
1,2,3,4,5
5,4,3,2,1

What I've tried so far is as below:
Code:
sub query {
        open (OUTPUT, "su - oracle -cf 'source .profile; sqlplus $user/$passwd \@$sql_file'|") || die "Can open SQL\n";
        while (<OUTPUT>) {
                chop;
                ($rubbish,$value) = split(/\s+/);
                if (/^A/){
                        $list[0] = $value;
                } elsif (/B/){
                        $list[1] = $value;
                } elsif ( /C/ ){
                        $list[2] = "$value";
                } elsif ( /D/ ){
                        $list[3] = "$value";
                } elsif ( /E/ ){
                        $list[4] = "$value";
                } else { next;}
                push ( @array, \@list );
        }
        close(OUTPUT);
}
sub printSubs {
        $" = ",";
        for $a (@array){
                print "@$a\n";
        }
}

But that does not work.. it just prints out the last record many times.. Smilie
So would someone have any ideas how to fill the array?
# 2  
Old 03-18-2011
Code:
#!/usr/bin/perl

open (FH,"Outputfile") or die "FAIL- $!\n";
while (<FH>) {
chomp;
@fields=split(/\s+/);
push(@{$fields[0]},$fields[1]);
$hash{$fields[0]}=\@{$fields[0]};
}

for($i=0;$i<($./5);$i++) {
foreach (sort(keys(%hash))) {
printf "%s ",$hash{$_}[$i];
}
print "\n";
}

# 3  
Old 03-18-2011
Quote:
Originally Posted by Juha
...
What I've tried so far is as below:
Code:
sub query {
        open (OUTPUT, "su - oracle -cf 'source .profile; sqlplus $user/$passwd \@$sql_file'|") || die "Can open SQL\n";
        while (<OUTPUT>) {
                chop;
                ($rubbish,$value) = split(/\s+/);
               if (/^A/){
                       $list[0] = $value;
               } elsif (/B/){
                       $list[1] = $value;
               } elsif ( /C/ ){
                       $list[2] = "$value";
               } elsif ( /D/ ){
                       $list[3] = "$value";
               } elsif ( /E/ ){
                       $list[4] = "$value";
               } else { next;}
               push ( @array, \@list );
        }
        close(OUTPUT);
}
sub printSubs {
        $" = ",";
        for $a (@array){
                print "@$a\n";
        }
}

But that does not work.. it just prints out the last record many times..
So would someone have any ideas how to fill the array?
Your code is unnecessarily complicated.
The part in blue color fills up the indexes 0..4 of the array @list.
All you have to do is - print the array @list as soon as you've processed 5 records.

The part in red color is just overkill.

Here's the modified portion of the code -

Code:
while (<OUTPUT>) {
 chomp;
 ($rubbish,$value) = split(/\s+/);
 if (/^A/){
   $list[0] = $value;
 } elsif (/B/){
   $list[1] = $value;
 } elsif (/C/){
   $list[2] = $value;
 } elsif (/D/){
   $list[3] = $value;
 } elsif (/E/){
   $list[4] = $value;
 } else { next }
 print join(",", @list),"\n" if ($.%5 == 0); 
}

Here's the modified code in action -

Code:
$
$
$ # display the content of the data file "f2"
$
$ cat f2
A   1
B   2
C  3
D   4
E  5
B  4
C    3
A  5
E  1
D  2
$
$
$ # display the content of the Perl program "f2.pl"
$
$ cat -n f2.pl
    1  #!perl -w
    2  my $rubbish;
    3  $file="f2";
    4  open (OUTPUT, "<", $file) || die "Can't open $file\n";
    5  while (<OUTPUT>) {
    6    chomp;
    7    ($rubbish,$value) = split(/\s+/);
    8    if (/^A/){
    9      $list[0] = $value;
   10    } elsif (/B/){
   11      $list[1] = $value;
   12    } elsif (/C/){
   13      $list[2] = $value;
   14    } elsif (/D/){
   15      $list[3] = $value;
   16    } elsif (/E/){
   17      $list[4] = $value;
   18    } else { next }
   19    print join(",", @list),"\n" if ($.%5 == 0);
   20  }
   21  close(OUTPUT);
   22
$
$
$ # Run the Perl program
$
$ perl f2.pl
1,2,3,4,5
5,4,3,2,1
$
$

As for why your code doesn't work - you keep pushing the reference to the array @list in the array @array. When the array @list changes, the reference to @list now points to the "current" array.

Code:
After 1st record is processed, @list = (1)             and \@list = pointer to @list i.e. it points to (1)
After 2nd record is processed, @list = (1, 2)          and \@list = pointer to @list i.e. it points to (1, 2)
After 3rd record is processed, @list = (1, 2, 3)       and \@list = pointer to @list i.e. it points to (1, 2, 3)
After 4th record is processed, @list = (1, 2, 3, 4)    and \@list = pointer to @list i.e. it points to (1, 2, 3, 4)
After 5th record is processed, @list = (1, 2, 3, 4, 5) and \@list = pointer to @list i.e. it points to (1, 2, 3, 4, 5)

So by the time you've processed the first five records, @list = (1,2,3,4,5) and \@list = pointer to (1,2,3,4,5) and since first 5 elements of @array are all \@list, they all point to (1,2,3,4,5) as well.

From record 6 onwards, you overwrite the array @list. (You should print it before overwriting.) Records 6 through 10 do the same thing again.

So at the end, you have 10 elements in @array, all of which are references to the latest array i.e. (5,4,3,2,1).

HTH,
tyler_durden

Further thoughts: you could change your Oracle SQL query to return the comma-delimited string of values directly. Thereby you can avoid all this processing in Perl.
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

awk to parse comma separated field and removing comma in between number and double quotes

Hi Experts, Please support I have below data in file in comma seperated, but 4th column is containing comma in between numbers, bcz of which when i tried to parse the file the column 6th value(5049641141) is being removed from the file and value(222.82) in column 5 becoming value of column6. ... (3 Replies)
Discussion started by: as7951
3 Replies

2. Shell Programming and Scripting

Need comma separated output

Hi, I am having the file with server names & its corresponding process, i need your help how to convert into comma separated output between server & app #cat apps.txt Server1 oracle was Server2 http webadmin Server3 tsm db2 My requirement is like below. Server1,oracle/was... (5 Replies)
Discussion started by: ksgnathan
5 Replies

3. Shell Programming and Scripting

awk print - fields separated with comma's need to ignore inbetween double quotes

I am trying to re-format a .csv file using awk. I have 6 fields in the .csv file. Some of the fields are enclosed in double quotes and contain comma's inside the quotes. awk is breaking this into multiple fields. Sample lines from the .csv file: Device Name,Personnel,Date,Solution... (1 Reply)
Discussion started by: jxrst
1 Replies

4. Shell Programming and Scripting

Output of command in comma separated list

Hi; I have an output of a particular command say $command fstl:r-x ajay:r-x how can i get this in comma separated list, eg: fstl:r-x,ajay:r-x Thnks; (4 Replies)
Discussion started by: ajaypadvi
4 Replies

5. Shell Programming and Scripting

Help parse comma separated list

I have a list of files with the same name, but they have a different date stamp in the name. I can find the first file, but I need to find the second file. I am using this information to create a variable I use later. Here is a example of how I find the first file. "ls -mr... (11 Replies)
Discussion started by: NoMadBanker
11 Replies

6. Shell Programming and Scripting

Its PERL + Comma separated seventh field

Hi Friends, I'm working on a perl script, which seems to be simpler. But I'm very new to PERL scripting. I have a comma separated data file, from which I need to extract only the seventh field data out of available twenty fields to an array using perl. Any help would be much appreciated. ... (17 Replies)
Discussion started by: ganapati
17 Replies

7. Shell Programming and Scripting

Parse apart strings of comma separated data with varying number of fields

I have a situation where I am reading a text file line-by-line. Those lines of data contain comma separated fields of data. However, each line can vary in the number of fields it can contain. What I need to do is parse apart each line and write each field of data found (left to right) into a file.... (7 Replies)
Discussion started by: 2reperry
7 Replies

8. Shell Programming and Scripting

Unix shell script to parse the contents of comma-separated file

Dear All, I have a comma-separated file. 1. The first line of the file(header) should have 4 commas(5 fields). 2. The last line of the file should have 1 comma(2 fields). Pls help me in checking this condition in a shell script. And the number of lines between the first line and last... (11 Replies)
Discussion started by: KrishnaSaran
11 Replies

9. Shell Programming and Scripting

To parse through the file and print output using awk or sed script

suppose if u have a file like that Hen ABCCSGSGSGJJJJK 15 Cock ABCCSGGGSGIJJJL 15 * * * * * * : * * * . * * * : Hen CFCDFCSDFCDERTF 30 Cock CHCDFCSDHCDEGFI 30 * . * * * * * * * : * * :* : : . The output shud be where there is : and . It shud... (4 Replies)
Discussion started by: cdfd123
4 Replies
Login or Register to Ask a Question