pingme8705 has asked for the wisdom of the Perl Monks concerning the following question:

hi ! this is the contents of the text/excel file.
logging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device2 Tue Sep 5 10:26:44 GMT 2005
i want to check for the device1 ond put its %value for /,/varin column of the excel sheet.there will be some 25 devices.

Replies are listed 'Best First'.
Re: new : greping
by GrandFather (Saint) on Sep 07, 2005 at 11:12 UTC

    This is my best current guess at what you are trying to do:

    use warnings; use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("data.xls"); my $worksheet = $workbook->add_worksheet(); $worksheet->write ("A1", 'Device'); $worksheet->write ("B1", '/var'); $worksheet->write ("C1", '/'); $worksheet->write ("D1", 'interleaved'); my $row = 2; #Assume data is actually on one line while (<DATA>) { my ($p1, $p2, $p3, $device) = /(?:\. ){3}(\d+)%\s\/var\s(\d+).*?(\d+ +)%\sInterleaved (\w+)/; $worksheet->write("A$row", $device); $worksheet->write("B$row", $p1); $worksheet->write("C$row", $p2); $worksheet->write("D$row", $p3); ++$row; print "$device $p1, $p2, $p3\n"; } $workbook->close (); __DATA__ 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 Tue Sep 9 11:26: +44 ist 2005 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device2 Tue Sep 5 10:26: +44 GMT 2005

    Prints:

    device1 56, 38, 31 device2 56, 38, 31

    It pulls report lines from a file (in the sample code from the __DATA__ section), checks that the data pertains to device1, extracts the first two % values and writes those to columns A and B respectively in an Excel spreadsheet file.

    Update: Updated to extract all parameters and to print collected data

    Perl is Huffman encoded by design.
Re: new : greping
by GrandFather (Saint) on Sep 07, 2005 at 10:40 UTC

    I presume that this is actually the contents of a text file created by some sort of logging device and that you wish to parse out the (in the sample data case) 56% and 38% values for device 1, and place those into an excel file?

    If that is the case, the second thing that you need is Spreadsheet::WriteExcel. I'll come back to the first thing you need soon.


    Perl is Huffman encoded by design.
Re: greping for a value
by Anonymous Monk on Sep 07, 2005 at 10:43 UTC
    Not sure about the excel part, but this might be a starting point...

    use strict; use warnings; $_ = q|device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 + Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 56% +/var 44% / 31%|; my @arr = /(device\d+)\sis\s.+?\/var\s+(\d+%)/g; print "@arr";
      about the excel part:

      if you create a csv file that is tab delimited and name it with an extension of .xls, Excel will correctly open it.

      To get the device name as well, I'd do it as follows:
      use strict; use warnings; my %devices; $_ = q|device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 + Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 56% +/var 44% / 31%|; my @arr = /(device\d+)\sis\s.+?\/var\s+(\d+%)/g; %devices = @arr; open(XLS, ">/path/to/file.xls") or die "Could not open file: " . $!; foreach my $device (sort keys (%devices)) { print XLS $device . "\t" . $devices{$device} . "\n"; } close XLS;
      Cheers
      Sven
        hi !
        my @arr = /(device\d+)\sis\s.+?\/var\s+(\d+%)/g;
        gives the output for /var
        device1 38% device2 44%
        but it should be
        device1 56% device2 56%
        i m now checking on that and also trying to take the data from the text file itself.
      hi ! Thank you it helped to narrow down a bit ! i m from india. if u come anytime to india tell me i here to help ! just mail me to pingme8705@gmail.com! thank u man ! it helped to narrow down!
Re: new : greping
by GrandFather (Saint) on Sep 08, 2005 at 04:40 UTC

    Version of code that reads the data from a file. Data is identical to that in the __DATA__ section of my previous post.


    Perl is Huffman encoded by design.
      hi grandfather ! It gave an error mesg : " use of unintialised value in concatanation or string " i am checking on it !
Re: new : greping
by GrandFather (Saint) on Sep 08, 2005 at 05:39 UTC

    Yet another variation. This time to read files formatted per OP's sample data.

    Update: Fix write to spreed sheet (required quotes).

    Perl is Huffman encoded by design.
      hi father ! If the file is like this :
      logging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 96% /var 88% / 100% Interleaved device2 Tue Sep 5 10:26:44 GMT 2005 logging to device5-PPP is 2.3.5.1 . . . 156% /var 138% / 131% Interleaved device1 Tue Sep 9 11:26:44 ist 2005 logging to device8-PPm is 2.3.5.1 . . . 596% /var 688% / 100% Interleaved device2 Tue Sep 5 10:26:44 GMT 2005
      then the code doesn't shows the correct device name. it shows ...
      device1 56,38,31 device2 96,88,100 device1 156,138,131 device2 596,688,100
      and excel no change !

        Final modification to code for extended file syntax

        use warnings; use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("data.xls"); my $worksheet = $workbook->add_worksheet(); $worksheet->write ("A1", 'Device'); $worksheet->write ("B1", '/var'); $worksheet->write ("C1", '/'); $worksheet->write ("D1", 'interleaved'); my $row = 2; my $line = ''; my $device; open inFile, '<', 'data.txt' or die "Couldn't open data.txt: $!"; while (! eof inFile) { $line .= ' ' . <inFile>; chomp $line; next if ! ($line =~ /logging\sto\s(device.*?)\s+/i) and ! eof inFile +; my $nextDevice = $1; if ($line =~ /(\d+)%\s+\/var\s+(\d+).*?(\d+)%\s+Interleaved\s+(\w+)/ +i) { $worksheet->write("A$row", "$device"); $worksheet->write("B$row", "$1"); $worksheet->write("C$row", "$2"); $worksheet->write("D$row", "$3"); ++$row; print "$device $1, $2, $3\n"; } $device = $nextDevice; $line = ''; } close inFile; $workbook->close ();

        Perl is Huffman encoded by design.
      hi father ! In the excel sheet this was the output:
      Device /var / interleaved B2 B3
      but it gave correct output in the screen ( i mean the command prompt)
Re: new : greping
by GrandFather (Saint) on Sep 09, 2005 at 09:40 UTC

    Here is a different technique that avoids the nasty regex that was growing out of control:

    use warnings; use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("data.xls"); my $worksheet = $workbook->add_worksheet(); $worksheet->write ("A1", 'Device'); $worksheet->write ("B1", '/var'); $worksheet->write ("C1", '/'); $worksheet->write ("D1", 'interleaved'); $worksheet->write ("E1", 'avm'); $worksheet->write ("F1", 'fre'); $worksheet->write ("G1", 'cs'); $worksheet->write ("H1", 'us'); $worksheet->write ("I1", 'sy'); $worksheet->write ("J1", 'id'); $worksheet->write ("K1", 'Date'); my $row = 1; open inFile, '<', 'data.txt' or die "Couldn't open data.txt: $!"; while (<inFile>) { chomp; next if ! length $_; if (/logging to (.*?) is/i) { ++$row; $worksheet->write("A$row", "$_"); print "\n$1 "; next; } elsif (/logging to (.*?) is/i) {$worksheet->write("B$row", "$1");} elsif (/(\d+)% \/var/i) {$worksheet->write("C$row", "$1");} elsif (/(\d+)% \//i) {$worksheet->write("D$row", "$1");} elsif (/(\d+)% Interleaved/i) {$worksheet->write("E$row", "$1");} elsif (/(\d+) (\d+) (\d+) (\d+) (\d+) (\d+)/i) { $worksheet->write("F$row", "$1"); $worksheet->write("F$row", "$2"); $worksheet->write("F$row", "$3"); $worksheet->write("F$row", "$4"); $worksheet->write("F$row", "$5"); $worksheet->write("F$row", "$6"); print "$1 $2 $3 $4 $5 $6 "; next; } else {next;} print "$1 "; } close inFile; $workbook->close ();

    Perl is Huffman encoded by design.
Re: new : greping
by wfsp (Abbot) on Sep 08, 2005 at 12:30 UTC
    Hi pingme8705,

    Perhaps loading the data into a HoA might help getting hold of the fields a bit easier.

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my (%data, $device); while (my $line = <DATA>){ chomp $line; next if $line =~ /^\s*$/; if ($line =~ /logging to ([\w-]+)/){ $device = $1; next; } push @{$data{$device}}, $line; } print Dumper(\%data); __DATA__ logging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 96% /var 88% / 100% Interleaved device2 Tue Sep 5 10:26:44 GMT 2005 logging to device5-PPP is 2.3.5.1 . . . 156% /var 138% / 131% Interleaved device1 Tue Sep 9 11:26:44 ist 2005 logging to device8-PPm is 2.3.5.1 . . . 596% /var 688% / 100% Interleaved device2 Tue Sep 5 10:26:44 GMT 2005
    output
    ---------- Capture Output ---------- > "C:\Perl\bin\perl.exe" ping.pl $VAR1 = { 'device8-PPm' => [ '596% /var', '688% /', '100% Interleaved', 'device2', 'Tue Sep 5 10:26:44 GMT 2005' ], 'device5-PPP' => [ '156% /var', '138% /', '131% Interleaved', 'device1', 'Tue Sep 9 11:26:44 ist 2005' ], 'device1' => [ '56% /var', '38% /', '31% Interleaved', 'device1', 'Tue Sep 9 11:26:44 ist 2005' ], 'device2' => [ '96% /var', '88% /', '100% Interleaved', 'device2', 'Tue Sep 5 10:26:44 GMT 2005' ] }; > Terminated with exit code 0.
      hi wfsp !
      ogging to device1 is 2.3.5.1 . . . 56% /var 38% / 31% Interleaved disks faults avm fre cs us sy id 504956 19880 32 3 24 72 device1 Tue Sep 9 11:26:44 ist 2005 logging to device2 is 2.3.5.1 . . . 96% /var 88% / 100% Interleaved disks faults avm fre cs us sy id 5049 198 32 3 24 72 device2 Tue Sep 5 10:26:44 GMT 2005 logging to device5-PPP is 2.3.5.1 . . . 156% /var 138% / 131% Interleaved disks faults avm fre cs us sy id 956 190 32 3 24 72 device5-PPP Tue Sep 9 11:26:44 ist 2005 logging to device8-PPm is 2.3.5.1 . . . 596% /var 688% / 100% Interleaved device8-PPm disks faults avm fre cs us sy id 56 19880 32 3 24 72 Tue Sep 5 10:26:44 GMT 2005
      this is the content of the logs we get ! and with the help of Grandfather we able to get a sort of partial output. but we need to get the values of avm,fre,id which are in the next line seperated by spaces and also the time stamp thats displayed on the next line in the excel sheet ! this is the code we have now.
      use warnings; use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("data.xls"); my $worksheet = $workbook->add_worksheet(); $worksheet->write ("A1", 'Device'); $worksheet->write ("B1", '/var'); $worksheet->write ("C1", '/'); $worksheet->write ("D1", 'interleaved'); my $row = 2; my $line = ''; my $device; open inFile, '<', 'logs.txt' or die "Couldn't open data.txt: $!"; while (! eof inFile) { $line .= ' ' . <inFile>; chomp $line; next if ! ($line =~ /logging\sto\s(.*?)\s+/i) and ! eof inFile; my $nextDevice = $1; if ($line =~ /(\d+)%\s+\/var\s+(\d+).*?(\d+)%\s+Interleaved\s+(\w+)/ +i) { $worksheet->write("A$row", "$device"); $worksheet->write("B$row", "$1"); $worksheet->write("C$row", "$2"); $worksheet->write("D$row", "$3"); ++$row; print "$device $1, $2, $3\n"; } $device = $nextDevice; $line = ''; } close inFile; $workbook->close ();
      i am making modifaication in the $line to grep the need. <code>