Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Cutting text from the end of the file and adding it to the top

by oysterperl (Novice)
on Sep 30, 2019 at 07:08 UTC ( [id://11106860]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Guys, I have the text below in a file:
a b c d e f g h aa bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1 +4 15 16 I want the following: a b c d e f g h aa 1 2 3 4 5 6 7 8 bb 8 9 10 11 12 13 14 15 cc dd aa bb cc dd aa bb cc dd
All the rows need to be filled and I have values which are at the end of the file. How can I do this? Any tips/help is appreciated. Thanks!

Replies are listed 'Best First'.
Re: Cutting text from the end of the file and adding it to the top
by LanX (Saint) on Sep 30, 2019 at 12:55 UTC
    What did you try?

    Update

    This

    > 1. Calculate number of columns from the header. 2. Start splitting the last row in the file by the number of columns. 3. Paste the splits starting from the second row.

    Sounds like a plan, where are your problems?

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Cutting text from the end of the file and adding it to the top
by GrandFather (Saint) on Sep 30, 2019 at 14:17 UTC

    Why? Tell us more about the reason you are doing this and we can give more appropriate help. If this is a homework exercise then tell us what you were actually asked to do (and tell us it is homework). If it is some business application then disguising the data is fine, but if you don't give us some context we end up second, third and fifth guessing what you want to do.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Cutting text from the end of the file and adding it to the top -- oneliner
by Discipulus (Canon) on Sep 30, 2019 at 16:59 UTC
    Hello oysterperl,

    as new user, always remember to show what you already tried, or you risk to obtain back working solutions not suitable for your Perl level, as the following one ;)

    cat data-sample.txt a b c d e f g h aa bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1 +4 15 16 #NB pay attention to windows double quotes! perl -M"0;$t=qq(\t)" -F"\s+" -le "$.==1?@h=@F:eof?@n=@F:push@l,$F[0]}{ +print$t,join$t,@h;print join$t,shift@l,map{shift@n}1..$#h,$/while@l" + data-sample.txt a b c d e f g h aa 1 2 3 4 5 6 7 8 bb 9 10 11 12 13 14 15 16 cc dd aa bb cc dd aa bb cc dd

    you can prepend -MO=Deparse to the above to see it a bit de-obfuscated. It uses eskimo greeting and maori farewel (;) from perlsecret

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Cutting text from the end of the file and adding it to the top
by Athanasius (Archbishop) on Sep 30, 2019 at 07:40 UTC

    Hello oysterperl, and welcome to the Monastery!

    I assume the repetition of “8” in the desired output is a mistake? If so, the following script should give you an idea of how to proceed:

    use strict; use warnings; my $header = <DATA>; chomp $header; $header =~ s/ ^ \s+ //x; my @columns = split /\s+/, $header; my $columns = scalar @columns; my @lines = <DATA>; my $data = pop @lines; chomp $data; my @data = split /\s+/, $data; print "\t", join("\t", @columns), "\n"; for my $line (@lines) { chomp $line; print $line; for my $i (1 .. $columns) { print("\t", shift @data) if @data; } print "\n"; } __DATA__ a b c d e f g h aa bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1 +4 15 16

    Output:

    17:37 >perl 2021_SoPW.pl a b c d e f g h aa 1 2 3 4 5 6 7 8 bb 9 10 11 12 13 14 15 16 cc dd aa bb cc dd aa bb cc dd 17:37 >

    I don’t know what you mean by “All the rows need to be filled” though.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Hi, Thank you for your quick response. By all rows need to be filled, I meant that the same logic needs to be used to fill up all the rows. The top level algo will be: 1. Calculate number of columns from the header. 2. Start splitting the last row in the file by the number of columns. 3. Paste the splits starting from the second row. I tried the script and it is not giving the desired output. Input:
      a b c d e f g h aa bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1 4 15 16
      Output with your script snippet:
      a b c d e f g h aa 4 15 16 bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1
      Desired:
      a b c d e f g h aa 1 2 3 4 5 6 7 8 bb 9 10 11 12 13 14 15 16 cc 17 18 19 20 21 22 23 24 dd 25 26 27 28 29 30 31 32 aa 33 34 35 36 37 38 39 40 bb 41 42 43 44 45 46 47 48 cc 49 50 51 52 53 54 55 56 dd 57 58 59 60 61 62 63 64 aa 65 66 67 68 69 70 71 72 bb 73 74 75 76 77 78 79 80 cc 81 82 83 84 85 86 87 88 dd 89 90 91 92 93 94 95 96 1 2 3 4 5 6 7 8 9 10 11 12 13 1 +4 15 16 17 18 19 20 21 22 23 24 25 + 26 27 28 29 30 31 32 33 34 35 36 3 +7 38 39 40 41 42 43 44 45 46 47 48 + 49 50 51 52 53 54 55 56 57 58 59 6 +0 61 62 63 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 80 81 82 8 +3 84 85 86 87 88 89 90 91 92 93 94 + 95 96

        So, you are saying that the numbers in the input are essentially irrelevant. SSCCE:

        #!/usr/bin/env perl use strict; use warnings; my @lines = <DATA>; print shift @lines; chomp @lines; my $perline = 8; my @num; my @numline = (1 .. $perline); my $fmt = '%s ' . '%5i' x $perline . "\n"; for my $line (@lines) { if ($line =~ /^1/) { print join (' ', @num) . "\n"; last; } printf $fmt, $line, @numline; push @num, @numline; $_ += $perline for @numline; } __DATA__ a b c d e f g h aa bb cc dd aa bb cc dd aa bb cc dd 1 2 3 4 5 6 7 8 9 10 11 12 13 1 +4 15 16
Re: Cutting text from the end of the file and adding it to the top
by Anonymous Monk on Sep 30, 2019 at 16:38 UTC
    "Online forums are not code-writing services." What you've described here (vaguely) is a task that will be solved by constructing an appropriate multi-step algorithm. While the community might be able to assist with specific parts of it – such as, "how do I count the number of letters in the first row of the data?" – we really can't be expected to do your work for you, nor to proofread and correct the first script that you maybe threw together. This task has been handed to you, so you're going to be the primary one to fulfill it. We can help you, as a friendly community of experts, but only in targeted ways.
      we really can't be expected to do your work for you

      And, frankly, we can't expect you to be able to do any of the work. Thanks for "weighing in", though.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11106860]
Approved by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-25 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found