JumpOffBox
JumpOffBox

Reputation: 783

Perl - Formatting the output data

I have data output in the below format. I get this output from a command on console.

Number: 9
state: Online
Data:             W1F-9YN
Device: 41
Number: 10
state: Online
Inquiry Data:             W1-9YN                   
Device: 41
Number: 11
state: Online
Inquiry Data:             W1-9YN                   
Device: N/A
Number: 42
state: Online
Data:      WD-W WDZ-04J                

     But, now I want to change it to output in a table format. Like as shown below

Device   number  state    data
41        10     online   WY1-996
42        12     offline  WY2-996
.          .       .        .
.          .       .        .
.          .       .        .

I tried doing with code given below, but I am not able to arrange in right format and some time all data shows up in a single column. Could anyone help me out ?

open WDLIST, "Command";

while (<WDLIST>) {

    if (m/Device\s*:\s*(\d+)/) {

        $enDevice = $1;
        print "$enDevice";
    }

    if (m/Number\s*:\s*(\d+)/) {

        $umber = $1;
        print "$Number";
        chomp;
    }

    if (m/state\s*:\s*(w+)/) {

        $State = $1;
        print"$State";
    }

    if (m/Data\s*:\s*(w+)(d+)(\-)(\s)/) {

        $Data = $1;
        print"$Data";
    }
}

Thank You!

Upvotes: 1

Views: 879

Answers (1)

pmakholm
pmakholm

Reputation: 1548

You can use printf to format your output. The simplest solution would be to replace all your print statements with

printf "%-10s", $variable;

This would print the variable left justified in a 10 character wide column. In addition you need to print a newline either at the start or at the end of each block of data.

For a more complete solution I would gather all data in a hash for a row and print it whenever you detect the end of a block of data:

printf "%-10s %-10s %-10s %-10s\n", $info{device}, $info{number}, $info{state}, $info{data};

(or using a hash slice for less verbose code)

Based on the assumption that each Device field signifies the start of a new device. I would change you code to work like this:

open WDLIST, "Command";

my %device;

printf "%-10s %-10s %-10s %-10s\n", qw(Device number state data);
while (<WDLIST>) {
    if (m/Device\s*:\s*(\d+)/) {

        # Print previous device, if any.
        printf "%-10s %-10s %-10s %-10s\n", @data{ qw(id number state data) }
            if exists $device{id};

        # Reset the current device and set the id
        %device = ( id => $1 );
    }

    if (m/Number\s*:\s*(\d+)/) {
        $device{number} = $1;
    }

    if (m/state\s*:\s*(w+)/) {
        $device{state} = $1;
    }

    if (m/Data\s*:\s*(w+d+-\d+)/) {
        $device{data} = $1;
    }
}
# Print the last device (if any)
printf "%-10s %-10s %-10s %-10s\n", @data{ qw(id number state data) }
    if exists $device{id};

(I'm a bit unsure what the last regexp for the Data field really ought to be. Your example is not consistent. At least you would need to explain the relation between the data fields of your example input and in your example output)

Upvotes: 1

Related Questions