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

I have a text file that looks something like this:

A21 103 A22 103 A23 103 A25 103 A26 103 A27 103 12.3 7.3 .0289 179 2 5 1 4 3 1 + 0 0 0 A28 103 4.5 4.2 .0000 479 1 0 0 0 0 0 + 0 0 0 10.2 9.6 .0188 250 2 5 0 4 2 3 + 0 0 0 10.2 9.6 .0188 250 2 5 0 4 2 3 + 0 0 0 A29 103 4.5 4.2 .0000 479 1 0 0 0 0 0 + 0 0 0 10.2 9.6 .0188 250 2 5 0 4 2 3 + 0 0 0 A30 103 A32 103 4.5 4.2 .0000 479 1 0 0 0 0 0 + 0 0 0 10.2 9.6 .0188 250 2 5 0 4 2 3 + 0 0 0 A33 103 4.5 4.2 .0000 479 1 0 0 0 0 0 + 0 0 0 10.2 9.6 .0188 250 2 5 0 4 2 3 + 0 0 0 A34 103 A36 103 4.5 4.2 .0000 479 1 0 0 0 0 0 + 0 0 0

The data is separated by tabs or spaces

I wish to be able to read in the file, remove the lines with two batches of text(eg.'A21 103') unless they are followed by a longer line of data(eg.'12.3 7.3 .0289'...).

If they are followed by a longer line of data, to read the two batches of text and insert them at the beginning of the subsequent longer lines until the next short batch is found. And so on through the file.

In this example, I want the output therefore to look like this:

A27 103 12.3 7.3 .0289 179 2 5 1 4 3 + 1 0 0 0 A28 103 4.5 4.2 .0000 479 1 0 0 0 0 + 0 0 0 0 A28 103 10.2 9.6 .0188 250 2 5 0 4 2 + 3 0 0 0 A28 103 10.2 9.6 .0188 250 2 5 0 4 2 + 3 0 0 0 A29 103 4.5 4.2 .0000 479 1 0 0 0 0 + 0 0 0 0 A29 103 10.2 9.6 .0188 250 2 5 0 4 2 + 3 0 0 0 A32 103 4.5 4.2 .0000 479 1 0 0 0 0 + 0 0 0 0 A32 103 10.2 9.6 .0188 250 2 5 0 4 2 + 3 0 0 0 A33 103 4.5 4.2 .0000 479 1 0 0 0 0 + 0 0 0 0 A33 103 10.2 9.6 .0188 250 2 5 0 4 2 + 3 0 0 0 A36 103 4.5 4.2 .0000 479 1 0 0 0 0 + 0 0 0 0

The data lines may be in batches of one, two, three, four or even five lines before the short line which is actually a kind of a heading for the data that follows below it.

(The 'headings' without 'data' below them are not required and need to be dropped from the output, as stated above.)

I cannot find a way to do this.

I have googled a lot for examples but without any success. Hope someone can teach me how to do this.

Thank you very much for your help.

Replies are listed 'Best First'.
Re: Insert Text which is Read from the Line Above
by NetWallah (Canon) on Feb 26, 2016 at 20:15 UTC
    perl -ane "@F<3 and @hdr=@F,next; print qq|@hdr $_|" data1.txt
    Change to single quotes for Linux.

            "Think of how stupid the average person is, and realize half of them are stupider than that." - George Carlin

      And that is why I love Perl! I'd give you my whole days worth of ++ if I had more left. A pure work of art!

      Hi NetWallah.

      That is absolutely amazing.

      As I am part of the below average person group you will have to help me with one further question.

      I managed to capture the output through running the command on Explorer^2's DOS Command line option.

      I pasted the output into a text file and all my checks so far on your output after running the code on a 2600 line input file have found the output to be 100% correct.

      However, I need to capture the output in a more easy way.

      How do I insert this code into a .pl file? Do I need 'if ($line =~ ........' etc.

      If you can give me some idea on that it will help me so much for this particular program and many more in the future.

      Many, many, many thanks.

        #!perl use strict; my $infile = $ARGV[0]; my $outfile = $ARGV[1]; unless (@ARGV==2) { die "Usage : perl $0 infile outfile\n" }; open IN, '<',$infile or die "Could not open $infile : $!\n"; open OUT,'>',$outfile or die "Could not open $outfile : $!\n"; my @hdr; my $count_in; my $count_out; while (<IN>){ ++$count_in; my @f = split; if (@f<3){ @hdr = @f; } else { print OUT "@hdr $_"; ++$count_out; } } print "$count_in lines read from $infile\n"; print "$count_out lines written to $outfile\n"; close IN; close OUT;
        poj