Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Any thoughts?use strict; use warnings; use Data::Dumper; my %hash = (); my $string = ""; while(<DATA>) { $_ =~ s/\n/ /g; $string .= $_; } my @array = split (/\:\s+/, $string); print Dumper( @array ); __DATA__ VLAN : 1 Status : Enabled FID : 1 Name : DEFAULT VLAN VLAN Type: Permanent Last change: 2009-08-31 16:48:45 Egress Ports: host.0.1 Forbidden Egress Ports: ge.3.39 Untagged Ports: host.0.1
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Parsing issue
by vitoco (Hermit) on Sep 08, 2009 at 21:05 UTC | |
Problems detected in this output: The last point gave me an idea: Let all the words with exactly one space between them just before a colon be a key. So you have to be sure that a value need many spaces after it not to be considered as part of the key from the next line (trick one). Then, also split everywhere there are many spaces and treat them as another delimiter (trick two).
Output:
You were too close, but now you have to be sure that all possible values of 'VLAN Type' should not be so long to left only one space before 'Last change' field. | [reply] [d/l] [select] |
by Anonymous Monk on Sep 10, 2009 at 14:34 UTC | |
| [reply] |
by vitoco (Hermit) on Sep 10, 2009 at 19:30 UTC | |
Then, you can forget this trick and try some of the other ideas I gave, like parsing each row at a time and cut each record at fixed columns or use some other regexp to get field values.
Here, I used "(.*?)\s*" to get a trimmed value of any type field, but you should change each of them to a specific pattern for dates, integers... Update: Forgot one field... | [reply] [d/l] [select] |
by vitoco (Hermit) on Sep 11, 2009 at 14:43 UTC | |
I forgot to mention in my previous post that the if (pat1) {} elsif (pat2) {} elsif ... inside a while loop method is useful when data records is not always in the same order. In this case, where your "output" format is fixed, it's better (faster) to use a per line parsing method (no while):
This way, you can control other things like key names:
Thinking a bit more on my first script, I realize that the string can be also modified in the following way: add a new delimiter just before what we detect as a field name (words separated by exactly one space, before any colon followed by a space), then split:
I also changed the delimiter to another unused char, to differentiate it from the colon inside the time value when trimming out extra spaces. BTW, this was fun! | [reply] [d/l] [select] |
|
Re: Parsing issue
by toolic (Bishop) on Sep 08, 2009 at 20:09 UTC | |
Can you also show us what your hash should look like? | [reply] [d/l] [select] |