import itertools
import operator
a='''Linux 2014_01_24 CPU 10
Linux 2014_01_24 MEM 20
UNIX 2014_01_24 CPU 30
UNIX 2014_01_24 MEM 40'''.split("\n")
a=map(lambda x:x.split(" "),a)
for name,item in itertools.groupby(sorted(a,key=operator.itemgetter(2,1)),operator.itemgetter(2,1)):
print(name[0],name[1],end=" ")
for i in item:
print(i[-1],end=" ")
print("")
Hi Belajesuri,
Thanks alot for your Perl code and to the others also I would like to say thanks so much but I need a Perl script.
I try to reformat your code from one-liners to the common way of Perl language and it works.
My next question is how I can set the header "Linux" and "UNIX" as variables instead of static values?. so when the other line comes, the header will be added also as well as the value of CPU anf MEM (e.g. )?.
Linux 2014_01_24 CPU 10
Linux 2014_01_24 MEM 20
UNIX 2014_01_24 CPU 30
UNIX 2014_01_24 MEM 40
WINDOWS 2014_01_24 CPU 70
WINDOWS 2014_01_24 MEM 80
so the result will be = NAME TIME Linux UNIX WINDOWS.. so on
#!/usr/bin/perl
use strict;
my %table;
print "NAME TIME Linux UNIX\n";
foreach (<FH>)
{ chomp;
my @temp = split " ", $_;
if ($temp[0] eq "Linux")
{
$table{"$temp[2] $temp[1]"}[0] = $temp[3];
}
elsif($temp[0] eq "UNIX")
{
$table{"$temp[2] $temp[1]"}[1] = $temp[3];
}
}
print "$_ ${$table{$_}}[0] ${ $table{$_} }[1]" for (keys %table);
---------- Post updated at 10:19 PM ---------- Previous update was at 04:17 PM ----------
Hi Balajesuri,
I've made the script based on your original code and the desired output already oke. But I think my script is still ugly. may be you have a good solution for this?.
#!/usr/bin/perl
use strict;
use Data::Dumper;
my %table;
my $file = "convert_column.log";
open (FH, "<", $file) or die $!;
my @node_name;
foreach my $line (<FH>)
{
chomp;
my @temp = split " ", $line;
push @node_name, $temp[0];
}
my %seen;
my @node_name_without_duplicate;
for (@node_name)
{
$seen{$_}++;
next if $seen{$_}++>1;
push @node_name_without_duplicate, $_;
}
close (FH);
my $length_node = scalar @node_name_without_duplicate;
print "NAME TIME @node_name_without_duplicate\n";
open (FH, "<", $file) or die $!;
my %table;
foreach (<FH>)
{
for my $i (0 .. $length_node-1)
{
my @temp = split " ", $_;
if ($temp[0] eq $node_name_without_duplicate[$i])
{
$table{"$temp[2] $temp[1]"}[$i] = $temp[3];
}
}
}
close (FH);
for (keys %table)
{
print "$_ ";
for my $i (0 .. $length_node-1)
{
print " $table{$_}->[$i]";
}
print "\n";
}
You are reading the file twice - this should be avoided, unless absolutely necessary.
#! /usr/bin/perl
use warnings;
use strict;
my ($line, $k1, $k2);
my (@fld, @temp);
my (%os, %final);
open I, "< file";
while ( $line = <I> ) {
chomp ( $line );
@fld = split /\s+/, $line;
$os{$fld[0]} = 1;
${ $final{"$fld[2] $fld[1]"} }{$fld[0]} = $fld[3];
}
close I;
my @OS_list = sort ( keys %os );
print "NAME TIME @OS_list\n";
for $k1 ( keys %final ) {
print "$k1 ";
for $k2 ( @OS_list ) {
if ( defined ${ $final{$k1} }{$k2} ) {
print "${ $final{$k1} }{$k2} ";
}
else {
print "--- ";
}
}
print "\n";
}
[user@host ~]$ cat file
Linux 2014_01_24 CPU 10
Linux 2014_01_24 MEM 20
UNIX 2014_01_24 CPU 30
UNIX 2014_01_24 MEM 40
WINDOWS 2014_01_24 CPU 70
WINDOWS 2014_01_24 MEM 80
HPUX 2014_01_22 CPU 90
HPUX 2014_01_22 MEM 100
[user@host ~]$ ./test.pl
NAME TIME HPUX Linux UNIX WINDOWS
MEM 2014_01_22 100 --- --- ---
MEM 2014_01_24 --- 20 40 80
CPU 2014_01_24 --- 10 30 70
CPU 2014_01_22 90 --- --- ---
[user@host ~]$
root@maximus-netpune-21:/tmp# ./run
NAME TIME Linux UNIX WINDOWS HPUX
CPU 2014_01_22 --- --- --- 90
CPU 2014_01_24 10 30 70 ---
MEM 2014_01_22 --- --- --- 100
MEM 2014_01_24 20 40 80 ---