Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Gentleman, I'm lost.

by Ryanjohns
on Nov 26, 2016 at 05:07 UTC ( #1176579=perlquestion: print w/replies, xml ) Need Help??
Ryanjohns has asked for the wisdom of the Perl Monks concerning the following question:

I'm not going to insult you with my code. I'm trying to get each verse from the Bible onto it's own line.

For instance, I have this block of text:

3:3 And he shall offer of the sacrifice of the peace offering an

offering made by fire unto the LORD; the fat that covereth the

inwards, and all the fat that is upon the inwards, 3:4 And the two

kidneys, and the fat that is on them, which is by the flanks, and the

caul above the liver, with the kidneys, it shall he take away.

3:5 And Aaron's sons shall burn it on the altar upon the burnt

sacrifice, which is upon the wood that is on the fire: it is an

offering made by fire, of a sweet savour unto the LORD.

And I want the output to be line by line kind of like this:

3:3 And he shall offer of the sacrifice of the peace offering an offering made by fire unto the LORD; the fat that covereth the inwards, and all the fat that is upon the inwards,

3:4 And the two kidneys, and the fat that is on them, which is by the flanks, and the caul above the liver, with the kidneys, it shall he take away.

3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrifice, which is upon the wood that is on the fire: it is an offering made by fire, of a sweet savour unto the LORD.

I'm not a coder, I've never coded anything before, and I've been trying to teach myself specifically for this little project. AND I'M LOST

Update

I need to concatenate a string with the string before it as it reads. if that string doesn't start with a number

Replies are listed 'Best First'.
Re: Gentleman, I'm lost.
by karlgoethebier (Monsignor) on Nov 26, 2016 at 13:18 UTC
      ++karl! there is always a module on CPAN that do your job

      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: Gentleman, I'm lost.
by GrandFather (Sage) on Nov 26, 2016 at 05:17 UTC

    We are flattered that you think we can intuit your code and provide guidance without seeing it. The truth however is that we have no idea what you have tried nor where you are having trouble or even what you are using as a guide to get you started.

    So, in the first instance head on over to Tutorials and see how you get on there. I'd recommend that you don't try to solve the whole thing in one go. Instead work at it a tiny bit at a time. Have you even gotten a script to print "Hello world." when you run it? If not, that's your first task. Come back and ask if you have trouble doing that, or tell us it was a piece of cake and you are figuring out the next small piece.

    Premature optimization is the root of all job security
      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Gentleman, I'm lost.
by FreeBeerReekingMonk (Deacon) on Nov 26, 2016 at 08:18 UTC
    my $line_number = 0; foreach my $row(@content){ # count the current line number $line_number++; # remove the newline chomp($row); my $rowsaver = $row; if($rowsaver=~/^\d/){ # curent row starts with a decimal # no extra action required, just process it }else{ # ok, current row does not start with a decimal, # we need to add a newline to the output file # before we process this line print $fh "\n" if $line_number > 1; } : rest of your code

    So you can rewrite that code as:

    my $have_to_newline = $rowsaver=~/^\d/ ? 1 : 0 print $fh "\n" if $have_to_newline && $line_number > 1;

    This approach works, except for the first line, if that does not start with a decimal, then your output file will start with an empty line. that is why the if $line_number > 1; is there in the first example.

Re: Gentleman, I'm lost.
by haukex (Canon) on Nov 26, 2016 at 10:26 UTC

    Hi Ryanjohns,

    I'm not a coder, I've never coded anything before, and I've been trying to teach myself specifically for this little project.

    In that case, beginning with perlintro is probably the best first step. It will show you many of the basics, including how to open a file and loop over its lines. (However, I'm wondering about the code you posted in this reply, it looks like you've gotten past the basics?)

    This is one of those cases where first describing how you might solve the problem without code will probably help. If you're reading a file line-by-line, which makes sense if the input is large, note that normally each line read ends in a newline character, which you'd use chomp to remove. That'd be your input. Regular expressions, which would help you decide whether a line begins with a number, are described e.g. in perlretut.

    Now as for the concatenation, in Perl There Is More Than One Way To Do It (TIMTOWTDI), and it depends on how you want to accumulate the lines.

    If you don't want to accumulate the lines at all, you could simply print them back out, choosing to append a newline character \n only when appropriate.

    Or, you could store the lines in an array, using the push function to add them, outputting the elements of that array with the help of a loop or the join function, and then clearing that array every time you start a new set of lines.

    Or, you could accumulate the lines by appending them to a string, using the concatenation operator . (dot), described in perlop.

    In all three cases, you'll need to decide when you want the output to start a new line and when not (when to output the currently accumulated lines and clear the array or string). Note that if you use the condition "this line starts with a number" for outputting the previously accumulated lines, then you'll need to cover the case of the last lines read, since there's no following line to trigger the output, so you could handle that e.g. by adding one more output statement after the loop.

    Hope this helps,
    -- Hauke D

Re: Gentleman, I'm lost.
by FreeBeerReekingMonk (Deacon) on Nov 26, 2016 at 10:03 UTC
    Here is simplified code:
    while(<DATA>){ chomp; # remove newlines next unless $_; # no empty lines? # check if a newline is required s/(\d+:\d+)/\n${1}/; # make lines end in space (separate words) s/\s?$/ /; print; } print "\n"; # end __DATA__ 3:3 And he shall offer of the sacrifice of the peace offering an offering made by fire unto the LORD; the fat that covereth the inwards, and all the fat that is upon the inwards, 3:4 And the two kidneys, and the fat that is on them, which is by the flanks, and the caul above the liver, with the kidneys, it shall he take away. 3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrifice, which is upon the wood that is on the fire: it is an offering made by fire, of a sweet savour unto the LORD.

    Yields:

    3:3 And he shall offer of the sacrifice of the peace offering an offer +ing made by fire unto the LORD; the fat that covereth the inwards, an +d all the fat that is upon the inwards, 3:4 And the two kidneys, and the fat that is on them, which is by the +flanks, and the caul above the liver, with the kidneys, it shall he t +ake away. 3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrifi +ce, which is upon the wood that is on the fire: it is an offering mad +e by fire, of a sweet savour unto the LORD.

    I still need an example of a separate chapter, or are you doing each book separately?

    Here is the oneliner:

    cat chapter.txt | perl -pe 'chomp; next unless $_; s/(\d+:\d+)/\n${1}/ +;s/\s?$/ /;'

    Note: if you are using Windows, replace the single quotes to double quotes, i.e. perl.exe -pe "..."

      From that, try to expand:

      my @VERSES,$longline; while(<DATA>){ chomp; # remove newlines next unless $_; # no empty lines? # check if a newline is required s/(\d+:\d+)/\n${1}/; # make lines end in space (separate words) s/\s?$/ /; $longline .= $_; } @VERSES = split(/\n/, $longline); for my $verse (@VERSES){ # remove verse number from verse $verse=~s/(\d+:\d+)\s*//; my $versenumber = $1; print "# verse $versenumber #\n"; my @phrases = split(/\s*[,.;:]\s*/, $verse); for my $phrase (@phrases){ $_ = uc($phrase); # uppercase tr/0123456789/0000000000/; tr/ABCDEFGHIJKLMNOPQRSTUVWXYZ/12345678912345678912345678/; my $value = 0; $value += $_ for(split(//)); # sum print "TXT:$phrase\nNRX:$_ = $value\n"; } } __DATA__ 3:3 And he shall offer of the sacrifice of the peace offering an offering made by fire unto the LORD; the fat that covereth the inwards, and all the fat that is upon the inwards, 3:4 And the two kidneys, and the fat that is on them, which is by the flanks, and the caul above the liver, with the kidneys, it shall he take away. 3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrifice, which is upon the wood that is on the fire: it is an offering made by fire, of a sweet savour unto the LORD.

      Yields:

      # verse # # verse 3:3 # TXT:And he shall offer of the sacrifice of the peace offering an offer +ing made by fire unto the LORD NRX:154 85 18133 66659 66 285 113996935 66 285 75135 66659957 15 66659 +957 4145 27 6995 3526 285 3694 = 409 TXT:the fat that covereth the inwards NRX:285 612 2812 36459528 285 9551941 = 128 TXT:and all the fat that is upon the inwards NRX:154 133 285 612 2812 91 3765 285 9551941 = 134 # verse 3:4 # TXT:And the two kidneys NRX:154 285 256 2945571 = 71 TXT:and the fat that is on them NRX:154 285 612 2812 91 65 2854 = 87 TXT:which is by the flanks NRX:58938 91 27 285 631521 = 85 TXT:and the caul above the liver NRX:154 285 3133 12645 285 39459 = 98 TXT:with the kidneys NRX:5928 285 2945571 = 72 TXT:it shall he take away NRX:92 18133 85 2125 1517 = 64 # verse 3:5 # TXT:And Aaron's sons shall burn it on the altar upon the burnt sacrifi +ce NRX:154 11965'1 1651 18133 2395 92 65 285 13219 3765 285 23952 1139969 +35 = 237 TXT:which is upon the wood that is on the fire NRX:58938 91 3765 285 5664 2812 91 65 285 6995 = 178 TXT:it is an offering made by fire NRX:92 91 15 66659957 4145 27 6995 = 132 TXT:of a sweet savour unto the LORD NRX:66 1 15552 114639 3526 285 3694 = 108

      I am still wondering what you will use it for, the math looks complex

Re: Gentleman, I'm lost.
by Laurent_R (Canon) on Nov 26, 2016 at 12:14 UTC
    Perhaps a quick one-liner:
    $ echo "3:3 And he shall offer of the sacrifice of the peace offering +an > offering made by fire unto the LORD; the fat that covereth the > inwards, and all the fat that is upon the inwards, 3:4 And the two > kidneys, and the fat that is on them, which is by the flanks, and th +e > caul above the liver, with the kidneys, it shall he take away. > 3:5 And Aaron's sons shall burn it on the altar upon the burnt > sacrifice, which is upon the wood that is on the fire: it is an > offering made by fire, of a sweet savour unto the LORD. > " | perl -pe 's/[\r\n]+/ /g; s/(\d+:\d+)/\n$1/g;' 3:3 And he shall offer of the sacrifice of the peace offering an offe +ring made by fire unto the LORD; the fat that covereth the inwards, +and all the fat that is upon the inwards, 3:4 And the two kidneys, and the fat that is on them, which is by the + flanks, and the caul above the liver, with the kidneys, it shall he + take away. 3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrif +ice, which is upon the wood that is on the fire: it is an offering m +ade by fire, of a sweet savour unto the LORD.
    Update: Of course, the above seems to be long because of the need to echo some sample data for demonstrating the example, but if your input data is in a file named "bible.txt, it boils down to one code line:
    perl -pe 's/[\r\n]+/ /g; s/(\d+:\d+)/\n$1/g;' bible.txt
Re: Gentleman, I'm lost.
by AnomalousMonk (Chancellor) on Nov 26, 2016 at 13:14 UTC

    Ryanjohns: It looks like you've dropped this whole thread, in which case a note to that effect would be polite.

    If that is not the case, a note about the version of Perl you have available to work with would be helpful:
        perl -v
    on the command line (see perlrun for the  -v and all other switches). The Perl version you have is nice to know because, e.g., version 5.10 adds a bunch of neat features, especially regex extensions.


    Give a man a fish:  <%-{-{-{-<

Re: Gentleman, I'm lost.
by tybalt89 (Vicar) on Nov 26, 2016 at 19:50 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1176579 use strict; use warnings; $_ = do { local $/; <DATA> }; print map s/\s+/ /gr =~ s/\s*$/\n/gr, /(\b\d+:\d+\b(?:(?!\b\d+:\d).)*) +/gs; __DATA__ 3:3 And he shall offer of the sacrifice of the peace offering an offering made by fire unto the LORD; the fat that covereth the inwards, and all the fat that is upon the inwards, 3:4 And the two kidneys, and the fat that is on them, which is by the flanks, and the caul above the liver, with the kidneys, it shall he take away. 3:5 And Aaron's sons shall burn it on the altar upon the burnt sacrifice, which is upon the wood that is on the fire: it is an offering made by fire, of a sweet savour unto the LORD.
Re: Gentleman, I'm lost.
by BillKSmith (Parson) on Nov 26, 2016 at 14:14 UTC
    I think you will find this task easier to code if you think of it in terms of the desired output. Build each output line by adding strings to it until you find one that does not belong. Print the current output line and start a new one. When there is nothing left to add, print the final line.
    Bill

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2018-12-17 11:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How many stories does it take before you've heard them all?







    Results (72 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!