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

Hello

I have a text file that looks like this:
Nancy Location1 600.00 New service Single Stella Location2 1000.00 Replacement Single Julie Location3 400.00 Replacement Three Debbie Location4 800.00 New service Three <code> I need a perl script that generates a simple report like this, all the + columns properly aligned: <code> #Daily meter works Report# Current date #Some text# Name of consumer Subdivision Amount Type of work Phase Nancy Location1 600.00 New service Single Stella Location2 1000.00 Replacement Single Julie Location3 400.00 Replacement Three Debbie Location4 800.00 New service Three Total 2800 Signature
any quick code snippet anyone?

Any help will be appreciated.

Replies are listed 'Best First'.
Re: Text file processing question
by BrowserUk (Patriarch) on Aug 13, 2009 at 12:15 UTC

    Two lines should do the job:

    #! perl -slw use strict; print "Name of consumer Subdivision Amount Type of work Phase"; printf "%-14s %14s %7.2f %-14s %-s\n", m[(\S+)\s+(\S+)\s+(\S+)\s+(.+)\s+(\S+)$] while <DATA>; __DATA__ Nancy Location1 600.00 New service Single Stella Location2 1000.00 Replacement Single Julie Location3 400.00 Replacement Three Debbie Location4 800.00 New service Three

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      :) This is really cool.

      Way to go BrowserUk. Thanks a lot. I now have to get down to the business of understanding the regular expression.

      perl_seeker
        I now have to get down to the business of understanding the regular expression.

        There's not much to it really. Essentially the input file consists of 5 groups of non-whitespace characters interpersed with whitespace.

        The only fly in that ointment is the 4th field which itself contains whitepace, and so prevents trival parsing with split. Luckily, as only one field contains multiple words, we can let the regex engine sort it out for us. Ask it for the first 3 whitespace delimited fields, and the last one. And the fourth field is everything left over.

        You might find it clearer expanded out like this:

        m[ ( \S+ ) \s+ ( \S+ ) \s+ ( \S+ ) \s+ ( .+ ) \s+ ( \S+ ) $ ]x

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Text file processing question
by moritz (Cardinal) on Aug 13, 2009 at 11:22 UTC
    split on /\s{2,}/ or similar, and feed the data into Text::Table. Shouldn't be too hard.
Re: Text file processing question
by desemondo (Hermit) on Aug 13, 2009 at 11:26 UTC
    Give Perl6::Form a try - written by the Damian. Of course you may consider it an overkill for what you need to do - but in all likelihood, your final solution using Perl6::Form will be MUCH more robust than anything most people could put together - even if given a whole week to do so...

    http://search.cpan.org/~dconway/Perl6-Form-0.04/Form.pm

    If you read in your text file line by line, with each block of non-whitespace treated as an 'object' or 'cell' in your report, that should get you at least 99% of the way there - if not all...
Re: Text file processing question
by ww (Archbishop) on Aug 13, 2009 at 11:24 UTC
Re: Text file processing question
by bichonfrise74 (Vicar) on Aug 13, 2009 at 17:27 UTC
    Hi BrowserUK,

    That is a nice technique. I was contemplating to use the split function but when I saw the 4th field which has several spaces on it, then I realized that it could pose as a problem. Anyway, thanks for sharing this technique.