New to Perl, and its acting funny
Here's my code:
------------------------- #!/usr/bin/perl open (IN, "in.txt"); open (OUT, ">out.txt"); my $search1 = 'cup_cakes_sold = '; while (<IN>){ $found = (index($_, $search1)); if ($found){ $sep = (index($_, "")); $temp = (substr($_, $sep)); print OUT $temp."4"; } else{ print OUT $_; } } close IN; close OUT; ------------------------- Here's my in.txt file ------------------------- pancakes = 4 cup_cakes_sold = 3 ------------------------- Here's my out.txt file ------------------------- pancakes = 4 5 5 5 5cup_cakes_sold = 3 ------------------------- Now what I was trying to do was have out.txt be the same as before, but have my script change the cup_cakes_sold = 3 to cup_cakes_sold = 4. Can someone spot the mistake? This is my first perl script. |
Perl acting funny
Perl rarely acts "funny", but it can drive you nuts.
Here are a few tips that may help you get things going the way you want: $found = (index($_, $search1)); if ($found){ ... Your conditional logic will execute everytime EXCEPT when the in.txt record contains "cupcakes sold =", because the "index" function returns the offset of the beginning of the string you're looking for in a zero-based fashion. If it's found at the first character, index returns 0 (which is Boolean false). If index doesn't find the string, it returns -1, which is Boolean true. $sep = (index($_, "")); This line of code will always assign 0 to $sep, since your asking index to find a null string, which occurs everywhere, hence the first occurence is 0. Assuming that you just want to change the number of cupcakes from whatever it is to 4, consider this substituting this code instead of all that index and substring stuff: s/(cup_cakes_sold =).*$/\1 4/; Also, if you haven't already, buy these 2 O'Reilly books: Learning Perl Programming Perl Best regards, Walt Uotinen a.k.a. "The Perl Guy" around my office |
I'm not entirely sure what you're trying to do, but your first problem is that the perl function index doesn't return "false" when it doesn't find the value. Therefore your test always succeeds.
The second problem is that you then search for the empty string, which it finds straight away at position 0 (which is correct, the empty string is always the first substring that you can get in a string) Then you get the subset of the string starting from position 0 (the offset that you've just found) which returns the entire string, then you print that out, appending a "4" at the end. So I would expect your output to look like this: Code:
pancakes = 4 |
Quote:
for example modfied quote: " Best regards, Walt Uotinen a.k.a. "The Perl Guy" around my office :) " |
I want to change cup_cakes_sold = 3 to cup_cakes_sold = 4 without all the 4's everywhere. How do I do that?
|
Quote:
Code:
if ( found cup_cakes_sold ) { |
Quote:
you dont just give somebody the code you will put a trick in it and they figure it out |
Quote:
|
Yes, now I have a vague understanding of what I need to do, I just don't know how to do it.
What I want to do is count how many characters there are all the way up to the = sign in the sentence cup_cakes_sold = [some number], and then I need to print those x characters, then tell perl to print " 4" afterwards to do the effect of what I want. Now if it doesn't see that line in that string of code (correct term??), it is to print it and move on. Could someone tell me what and where I've done wrong with my true/false thing? I realize that its doing the -1 code, however, can someone provide either a solution or a working example so I can see how its supposed to work? |
One begins with Perl putting
Code:
use strict; |
That just resulted in the following erros:
Global symbol "$found" requires explicit package name at perltest.txt line 17. Global symbol "$found" requires explicit package name at perltest.txt line 18. Global symbol "$sep" requires explicit package name at perltest.txt line 19. Global symbol "$temp" requires explicit package name at perltest.txt line 20. Global symbol "$sep" requires explicit package name at perltest.txt line 20. Global symbol "$temp" requires explicit package name at perltest.txt line 21. Execution of perltest.txt aborted due to compilation errors. |
You'll find these useful:
http://perldoc.perl.org/ http://www.perlmonks.org/?node=Tutorials Also, if you have access to those links, I recommend the Perl Cookbook over Programming Perl. Your 1st task is to sort those issues caused by adding use strict; use warnings; I highly recommend you use those cmds in ALL your Perl progs, even the short temp throwaway ones. They'll save you so much grief in the long run. |
Here's a solution, based on waltuotinen's suggestion
Code:
use strict; The next two lines open the file descriptors. The while loop goes through the input file line by line. The we have the magic. We use perl's regular expression handling to perform a substitution on the input line. This basically says, find a line that contains "cup_cakes_sold =" and has multiple things after the equals sign. and substitute it with cup_cakes_sold= 4. The brackets in the regular expression allow us to save what is matched in the brackets and refer to it as $1. the "." in the regular expression means match any character. The * in the regular expression means match zero or more of the preceding character) in this case ".". the $ means match the end of the line. |
Perl acting funny
Try this code:
#!/usr/bin/perl open (IN, "in.txt"); open (OUT, ">out.txt"); my $search1 = 'cup_cakes_sold = '; while (<IN>){ if (/(cup_cakes_sold = )(\d+)/) { $newNum = $2 + 1; s/(cup_cakes_sold =).*/\1 $newNum/; } print OUT $_; } close IN; close OUT; It will identify any record read in from in.txt that contains "cup_cakes_sold = " followed by one or more digits, then it will add 1 to the digit(s) value, and replace the string "cup_cakes_sold = " with the same string followed by the newly incremented number (i.e., 3 becomes 4, 27 becomes 28, etc.). Walt |
To the OP: I understand you're more interested in understanding what went wrong in your program rather than receiving suggestions for improvement. I've worked on the the suggestions given by waltuotinen (Post #2) and I've changed other things as well. Here's your corrected program with the minimal changes.
Code:
#!/usr/bin/perl perldoc -f <functionname> is the also very useful. |
All times are GMT -5. The time now is 10:40 PM. |