http://qs321.pair.com?node_id=257290

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

I am attempting, to use perl to place text onto new lines. I have a tab delimited file which looks similar to this.

John Smith 25 May 2003 <job>Manager Clean-up
John Smith 25 May 2003 <job>Manager Clean-up <job>Manager Books
John Smith 25 May 2003 <job>Manager Clean-up <job>Manager Books <job>Manager Acounts

What I am trying to do is, where a 2nd, 3rd or more <job> appears, I want to place it onto a new line, but with the text up to the date with the information. The final output would look something like this.

John Smith 25 May 2003 <job>Manager Clean-up
John Smith 25 May 2003 <job>Manager Clean-up
John Smith 25 May 2003 <job>Manager Books

Can anybody help?

#!/usr/bin/perl -w use strict; open (INPUT, "jobs.txt"); open (OUTPUT, ">newjobs.txt"); while ( <INPUT> ) { my $TheLine = $_; while ($TheLine=~ [^\n]*##citation##[^\n]*##citation##[^\n]*##cita +tion##[^\n]*/i) { $TheLine=~ /([^\n]*)##citation##([^\n]*)##citation##([^\n]*)##cita +tion##([^\n]*)/$1\t$2\n$1\t$3\n$1\t$4/i; } while ($TheLine=~ /[^\n]*##citation##[^\n]*##citation##[^\n]*/i) { $TheLine=~ s/([^\n]*)##citation##([^\n]*)##citation##([^\n]*)/$1\t +$2\n$1\t$3/i; } print OUTPUT "$TheLine"; } close INPUT; close OUTPUT;

Replies are listed 'Best First'.
Re: Placing text onto multiple lines
by vladb (Vicar) on May 11, 2003 at 22:31 UTC
    This works for me:
    use strict; while (<DATA>) { chomp(); my ($first, @rest) = split "<job>"; print "$first<job>$_\n" for @rest; } __DATA__ John Smith 25 May 2003 <job>Manager Clean-up John Smith 25 May 2003 <job>Manager Clean-up <job>Manager Books John Smith 25 May 2003 <job>Manager Clean-up <job>Manager Books <job>M +anager Acounts
    And output:
    John Smith 25 May 2003 <job>Manager Clean-up John Smith 25 May 2003 <job>Manager Clean-up John Smith 25 May 2003 <job>Manager Books John Smith 25 May 2003 <job>Manager Clean-up John Smith 25 May 2003 <job>Manager Books John Smith 25 May 2003 <job>Manager Acounts


    _____________________
    "We've all heard that a million monkeys banging on a million typewriters will eventually reproduce
    the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true."

    Robert Wilensky, University of California

Re: Placing text onto multiple lines
by pzbagel (Chaplain) on May 11, 2003 at 22:36 UTC

    I'm going to assume that every input line is comprised of a name and data and then 1 or more <job>s.

    while(<INPUT>){ chomp; ($name,@jobs)=split /<job>/; for $job (@jobs) { print OUTPUT "$name <job>$job\n"; } }

    Good luck

Re: Placing text onto multiple lines
by Limbic~Region (Chancellor) on May 11, 2003 at 22:33 UTC
    Anonymous Monk,
    This seems like what you want, but if not - say so and I will try something else:

    #!/usr/bin/perl -w use strict; open (INPUT,"jobs.txt") or die "Unable to open input : $!"; open (OUTPUT,"jobs.txt") or die "Unable to open output : $!"; select OUTPUT; $\ = "\n"; while (<INPUT>) { chomp; my @fields = split /\t/; unless (@fields > 2) { print join "\t" , @fields; } else { my $firstfield = shift @fields; while (my $nextfield = shift @fields) { print $firstfield, "\t", $nextfield; } } } close INPUT; close OUTPUT;

    Cheers - L~R

    Update: Both vladb++ and pzbagel++ have simpler solutions than this. The only thing I would point out is you said tab delimited.