Perl - Looping through a file, changing behaviour by 'heading'
I have a series of files (one per site) that are structured so:
Code:
Servers: There's reasonable chance of adding more headings (when I decide what else needs documenting this way), too. In short, how do I do that? I'm assuming it's something I can append to Code:
while (<FILE>) Code:
while (<FILE>){ I'm sure this is a pretty common thing to need to do, but all I can find are tutorials on reading files line-by-line, and treating each line the same. |
That's exactly what I'd do TBH, what angle do you think that there is for improvement? I suppose you could have a separate function for each header type, and pass the file handle into each different function, with that function checking for a change of header each line, doesn't seem worth it, and probably end up with extra code.
Sure you can condense the code down: $services ? do something; $servers ? do something_else; or actually rejig slightly to have a single variable: Code:
while(<file>) { Code:
while(<file>) { |
Quote:
Code:
while($line !~ /^Services$/){ Cheers! |
Well unless you were using more advanced input, e.g. XML, you're going to have to be a bit repetative. I would personally stay within the simple constraints of the file format you've got, I'd not preempt anything at all, i.e. "do this until we see this" as maybe you won't see that header.
Hmm, I suppose (similar to my intial thoughts about going OTT with separate functions) you could make the while loop more conditional in the first instance, but whilst it'd condense the code, you're not going to make it more efficient per se. BTW I kept edited my reply, you might have missed some later bits... |
Ah, yeah, I'm already completely sold on plain text. Also, efficiency's not really of massive concern here - it's to run on a high-powered workstation and serve the pages to four people) - I'm just trying to get into the habit of doing things sensibly rather than assuming the first thing I come up with is the correct way.
The case statement is probably more sensible, though. Certainly closer to the way I'd do it in my head (I seem to have a mental blindspot where case is concerned). I'll carry on with it as I started, then. |
Hm, apparently case statements are less than straightforward in perl (might be where the mental block comes from...), but there's a similarly straightforward way to do it here:
http://www.perlmonks.org/?node=How%2...20statement%3F |
Total overkill but interesting none the less. You could use function pointers. Just always call the same function and just point it to different one depend on the heading you found.
Here is a link how function pointers work in perl http://www.mikey.com/mikey/2008/04/p...-pointers.html |
Quote:
|
Quote:
|
Quote:
For some ideas about why symbolic references are bad, see the following: http://perl.plover.com/varvarname.html http://perl.plover.com/varvarname2.html http://perl.plover.com/varvarname3.html Perl 5.10.1 (the current branch) supports given/when, which is like case on steroids. If you're using an earlier version of Perl, there are many good modules to get you case blocks. |
Quote:
When I reread the Op something came to my mind I did in PHP. I check on it when I'm at home but was something like this Code:
while ( ! feof($fh) ){ Dunno if this possible in perl and can be used within strict sense (I would wonder about this) |
Just for completion heres the code I used in php
Code:
while ( $line = fgets($hFile) ){ |
I had written a script, but then I realized that there's some key information I don't yet have. So, some questions:
Edit: Since I started writing it, here's the draft. It's probably not a real solution for you, but it may help some. Code:
#!/usr/bin/env perl |
Actually, the data rules appear to be
1. starts in 1st char pos (ie '^') 2, starts with capital (eg [A-Z] ) 3. one word (regex that ?) 4. ends with colon (ie ':' ) eg /:$/ so something like /^[A-Z] [a-z].* :$/ not exact Perl regex, but you get the idea. Edit; after some playing around I get /^[A-Z][a-z]{1,}:$/ |
Quote:
This is partly why I called it "cheating" (since I was not being especially careful there), but also why I asked for more information about the data. |
All times are GMT -5. The time now is 05:54 PM. |