Home > Archive > PERL Beginners > January 2006 > String Comparison in a File
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
String Comparison in a File
|
|
| olson_ord@yahoo.it 2006-01-10, 4:02 am |
| Hi,
I am new to perl. I wanted to use perl to make a small change to a
file.
I started out with trying to write this file to the screen, and make
the change that I wanted - but I don't see why this does not work. My
actual line in the file is something like
new_matrix.no_of_eqns = 32;
I would like that 32 to be changed to some other number. So I tried the
following script.
#!/usr/local/bin/perl
use strict;
use warnings;
use Tie::File;
print "Hello Starting the program \n";
tie my @lines, 'Tie::File', '/home/masca/org/main.cpp';
my $line;
my $str = 'new_matrix.no_of_eqns =';
foreach $line (@lines) {
#if($line =~ /"new_matrix.no_of_eqns ="/) {
if(index($line, $str)){
print $line; print"\n";
} else {
print "new_matrix.no_of_eqns = SomeNumber; \n";
exit(1);
}
}
It seems that this never gets into the else part of the if statement,
for both of the if statements i.e. the first commented out if, as well
as the second if.
I then tried something like
#!/usr/local/bin/perl
use strict;
use warnings;
print "Hello Starting the program \n";
my $str1 = 'new_matrix.no_of_eqns =';
my $str2 = ' new_matrix.no_of_eqns = 32;';
if(index($str2, $str1)){
print "$str1 is contained in $str2"; print"\n";
} else {
print "new_matrix.no_of_eqns = sdgsfsf; \n";
exit(1);
}
In this code I can get into the else part of the loop - but I cannot
understand why in the code above I never reach the else part, though
the string is there in the file.
I hope someone has an idea about this.
Regards,
O. O.
| |
| Paul Lalli 2006-01-10, 4:02 am |
| olson_ord@yahoo.it wrote:
> I started out with trying to write this file to the screen, and make
> the change that I wanted - but I don't see why this does not work. My
> actual line in the file is something like
> new_matrix.no_of_eqns = 32;
>
> I would like that 32 to be changed to some other number. So I tried the
> following script.
>
> #!/usr/local/bin/perl
> use strict;
> use warnings;
GOOD!!
> use Tie::File;
> print "Hello Starting the program \n";
> tie my @lines, 'Tie::File', '/home/masca/org/main.cpp';
>
> my $line;
> my $str = 'new_matrix.no_of_eqns =';
> foreach $line (@lines) {
You only use $line within this loop. Declare it here:
foreach my $line (@lines) {
> #if($line =~ /"new_matrix.no_of_eqns ="/) {
1) Do not put the quotes in there unless you actually want to match the
quotes.
2) . is a special character. Backslash it.
> if(index($line, $str)){
> print $line; print"\n";
Why are you separating those?
print "$line\n";
> } else {
> print "new_matrix.no_of_eqns = SomeNumber; \n";
> exit(1);
> }
> }
>
> It seems that this never gets into the else part of the if statement,
> for both of the if statements i.e. the first commented out if, as well
> as the second if.
>
> I then tried something like
>
> #!/usr/local/bin/perl
> use strict;
> use warnings;
> print "Hello Starting the program \n";
> my $str1 = 'new_matrix.no_of_eqns =';
> my $str2 = ' new_matrix.no_of_eqns = 32;';
>
> if(index($str2, $str1)){
> print "$str1 is contained in $str2"; print"\n";
> } else {
> print "new_matrix.no_of_eqns = sdgsfsf; \n";
> exit(1);
> }
>
> In this code I can get into the else part of the loop
Er. Not when I run it. When I run it, I get:
Hello Starting the program
new_matrix.no_of_eqns = is contained in new_matrix.no_of_eqns = 32;
which is the if block, not the else block
> - but I cannot
> understand why in the code above I never reach the else part, though
> the string is there in the file.
I don't necessarily believe you at this point. I would print out $line
at each step of the loop before the if statement, to see if it contains
what you think it contains.
Paul Lalli
| |
| usenet@DavidFilmer.com 2006-01-10, 4:02 am |
| olson_ord@yahoo.it wrote:
> I would like that 32 to be changed to some other number. So I tried the
> following script.
<snip script>
You're going to a lot of trouble there, my friend. How about simply
doing this:
#!/usr/bin/perl
use strict; use warnings;
use Tie::File;
tie my @lines, 'Tie::File', '/home/masca/org/main.cpp';
map {s/(new_matrix.no_of_eqns =)\s*\d+/$1 SomeNumber/} @lines;
__END__
--
http://DavidFilmer.com
| |
| olson_ord@yahoo.it 2006-01-10, 4:02 am |
| Thanks a Dave. Your suggestion is exactly what I wanted. However I
would have never dreamt of it as this is way above my level of perl.
I really find perl pretty hard to learn - but I am doing it, only
because I am sure that its powerful.
Regards,
O.O
| |
| olson_ord@yahoo.it 2006-01-10, 4:02 am |
| Dear Paul,
Thanks for taking time to reply to this post.
Paul Lalli wrote:
> Er. Not when I run it. When I run it, I get:
> Hello Starting the program
> new_matrix.no_of_eqns = is contained in new_matrix.no_of_eqns = 32;
> which is the if block, not the else block
>
Yes, I made a mistake here - I actually meant the opposite.
On looking over my problem today, I realized that my understanding of
index() was wrong. I thought that it returns a true or a false
depending upon if the sub-string is in the bigger string. However I
realized that it returns the index - and it case its not contained it
returns a -1.
As my text is never at the beginning of the line - the if statement
always evaluates to be true - I need to check if its equal to -1 to
actually do what I wanted.
Thank you,
O.O.
| |
| usenet@DavidFilmer.com 2006-01-10, 4:02 am |
| olson_ord@yahoo.it wrote:
> Thanks a Dave. Your suggestion is exactly what I wanted. However I
> would have never dreamt of it as this is way above my level of perl.
You're welcome. Most of the code I posted was YOUR own code, of course
- I just wrote one line that was my own, so maybe you aren't giving
yourself enough credit. You did well to use Tie::File to allow Perl to
process the file like an array, but you made extra work for yourself by
then iterating over each line of the file/array in a loop. All I did
was show you the map function, which does a lot of that for you.
For exmaple:
map {s/php/Perl/ig} @stuff;
will change each occurance of the string "php" to "Perl" anywhere it
occurs in the array @stuff (and if it's an array that's tied to a file,
it happens in the file). So that's all I really did when I wrote
map {s/(new_matrix.no_of_eqns =)\s*\d+/$1 SomeNumber/} @lines;
although the regular expression I used (to satisify your requirements)
may make the process look somewhat intimidating you're not used to
looking at that sort of thing. But the only difference between the two
"map" statements that I've shown here is the complexity of the regular
expression (and regexp's are prehaps one of the most difficult things
to learm - 'perldoc perlre' may be of great help to a patient reader -
note the early reference to perlrequick and perlretut).
Cheers!
--
http://DavidFilmer.com
| |
| usenet@DavidFilmer.com 2006-01-10, 4:02 am |
| olson_ord@yahoo.it wrote:
> Your suggestion is exactly what I wanted.
I was, however, remiss in my duties when I posted my reply. Some of
the regulars in this group may have wondered why (in a rare lapse) I
neglected to mention IO::All in lieu of Tie::File (as I am often
promoting the use of IO::All, especially to novice Perl programmers,
because it simplifies and de-mystifies many Perl IO operations).
You may wish to use IO::All instead of Tie::File (and nearly every
other IO core function and module that you ever need - one module does
it ::All). See my recent rantings at http://tinyurl.com/avkou where I
discussed exactly how and why IO::All makes a great alternative to
Tie::File.
| |
| O. Olson 2006-01-10, 4:02 am |
| Thanks Dave for this suggestion. I don't have this package on my system
- and I don't know how to install it. I would look into this problem
later when I find the time. (I have never installed anything on Linux
before - also I don't have admin rights on this machine.)
Regards,
Rio
|
|
|
|
|