Search and replace a string in files

K

Kapil Khosla

I am new to PERL and I am trying to write a script which can do the
following changes.

int Main() CHANGES TO int main()
#define Main main CHANGES TO #define main main
int Main(String *str) CHANGES TO int main(String *str)

Essentially I am just converting all the occurences of Main to main in
a file.

I read the chapter on Regular expressions and wrote the following
script to do a search for the pattern with Main in an array with the
same requirement.This works correctly for me.

##################
use strict;
my $i;
my @arrstr = ('Mainframe','#define main Main','int Main(String
^sd)','int Main()','DllMain','int Main(ad)','MainMain');

for( $i=0;$i<@arrstr;$i = $i+1 )
{
print "$arrstr[$i]\n";

if ($arrstr[$i] =~ m{\bMain(\(.*\))?$} )
{
print "String matched\n\n";
}
}

#################

Now, I dont know how to use this in a file and replace the string
matched with the corresponding lower case main.
This is what I could write till now.



open FILEHANDLE,"E:\\file.cpp" or die ("Could not open file for
reading");;

my @myfile = <FILEHANDLE>; # get the file in an arraylist

for $line(@myfile)
{
# search for a pattern, if exists, replace with the correct str ?? #
This is what I dont know how to do :(
}
close FILEHANDLE;


Can you help?
Thanks a lot.
Kapil
 
H

Henry Law

Essentially I am just converting all the occurences of Main to main in
a file.

If you're doing this as an exercise then fine (and my Perl is nothing
like good enough to help you); but if you just need it done then maybe
some other tool would be better? I think a good sed-ist would do this
in one line.

Henry Law <>< Manchester, England
 
P

Paul Lalli

I am new to PERL and I am trying to write a script which can do the
following changes.

int Main() CHANGES TO int main()
#define Main main CHANGES TO #define main main
int Main(String *str) CHANGES TO int main(String *str)

Essentially I am just converting all the occurences of Main to main in
a file.

I read the chapter on Regular expressions and wrote the following
script to do a search for the pattern with Main in an array with the
same requirement.This works correctly for me.

##################
use strict;
my $i;
my @arrstr = ('Mainframe','#define main Main','int Main(String
^sd)','int Main()','DllMain','int Main(ad)','MainMain');

for( $i=0;$i<@arrstr;$i = $i+1 )
{
print "$arrstr[$i]\n";

if ($arrstr[$i] =~ m{\bMain(\(.*\))?$} )
{
print "String matched\n\n";

That RegExp is far more complicated than it needs to be. You're searching
for: "Word boundary, followed by 'Main', then *optionally* followed by
parenthesized text, followed by end-of-line. Why do you care about the
parentheses and end of line? You said all you wanted to do was replace
"Main" with "main". So the match could just be:

m/\bMain/

}
}

#################

Now, I dont know how to use this in a file and replace the string
matched with the corresponding lower case main.
This is what I could write till now.



open FILEHANDLE,"E:\\file.cpp" or die ("Could not open file for
reading");;

my @myfile = <FILEHANDLE>; # get the file in an arraylist

for $line(@myfile)
{
# search for a pattern, if exists, replace with the correct str ?? #
This is what I dont know how to do :(
}
close FILEHANDLE;


Can you help?


You said you read the chapter on RegExps. Did you somehow skip over the
search-and-repalce operator? The line you're looking for is:

s/\bMain/main/;



HOWEVER, this is such a common task that your entire program can be
reduced to *one line* of Perl code:

perl -pi.bkp -e 's/\bMain/main/' filename.txt

(the .bkp of that line will create backups of your original file, just in
case you did something you didn't mean to.)

To understand how this works, do
perldoc perlrun
and search for the -p and -i switches.


Hope this helps,
Paul Lalli
 
P

Paul Lalli

If you're doing this as an exercise then fine (and my Perl is nothing
like good enough to help you); but if you just need it done then maybe
some other tool would be better? I think a good sed-ist would do this
in one line.

So would a good Perl programmer. :)

perl -pi.bkp -e 's/Main/main/' file.txt


Paul Lalli
 
H

Himanshu Garg

I am new to PERL and I am trying to write a script which can do the
following changes.

int Main() CHANGES TO int main()
#define Main main CHANGES TO #define main main
int Main(String *str) CHANGES TO int main(String *str)

Essentially I am just converting all the occurences of Main to main in
a file.

I read the chapter on Regular expressions and wrote the following
script to do a search for the pattern with Main in an array with the
same requirement.This works correctly for me.

##################
[Code that works on arrays]
#################

Now, I dont know how to use this in a file and replace the string
matched with the corresponding lower case main.
This is what I could write till now.


open FILEHANDLE,"E:\\file.cpp" or die ("Could not open file for
reading");;

my @myfile = <FILEHANDLE>; # get the file in an arraylist

for $line(@myfile)
{
#search for a pattern, if exists, replace with the correct str ??
# This is what I dont know how to do :(

$line =~ s/Main/main/g; # substitute every occurence of Main
with main.
print $line;
}
close FILEHANDLE;
The above would give the output to Standard output. If you want to
edit the file in place use the following with the three arguments
source_string new_string file_names:-

use English;
use strict;
use Tie::File;

if(scalar(@ARGV) < 3)
{
print STDERR "usage: $PROGRAM_NAME source_string new_string
file_names";
die;
}

my $original = $ARGV[0];
my $new = $ARGV[1];

foreach my $i(2 .. $#ARGV)
{
my @array;
tie @array, 'Tie::File', $ARGV[$i] or
die "cannot tie file $ARGV[$i],
$OS_ERROR";
for(@array)
{
s/$original/$new/g;
}
}
Can you help?
Thanks a lot.
Kapil

++imanshu.
 
T

Tad McClellan

Paul Lalli said:
So would a good Perl programmer. :)

perl -pi.bkp -e 's/Main/main/' file.txt


This is likely to be "better":

perl -pi.bkp -e 's/\bMain\b/main/g' file.txt
^^ ^^ ^
^^ ^^ ^


Or does the OP want "Maine" to become "maine"? ...
 
T

Tad McClellan

Kapil Khosla said:
I am new to PERL


No, you are new to Perl.

There is no PERL that I'm aware of.

Essentially I am just converting all the occurences of Main to main in
a file.

I read the chapter on Regular expressions


Excellent! Thank you for trying on your own before asking.

Now, I dont know how to use this in a file and replace the string
matched with the corresponding lower case main.


It kinda looks like you did not check the Perl FAQ before posting
to the Perl newsgroup though.

Please don't do that anymore.

Can you help?


Your Question is Asked Frequently:

How do I change one line in a file/
delete a line in a file/
insert a line in the middle of a file/
append to the beginning of a file?
 
K

Kapil Khosla

That RegExp is far more complicated than it needs to be. You're searching
for: "Word boundary, followed by 'Main', then *optionally* followed by
parenthesized text, followed by end-of-line. Why do you care about the
parentheses and end of line? You said all you wanted to do was replace
"Main" with "main". So the match could just be:

m/\bMain/


I am sorry, I should have been more clear the first time. I want the
RegExp pattern to match
#define Main main - MATCH
int Main() - MATCH
int Main(String * str) - MATCH

but NOT
Mainframe -- NO MATCH
MainMain -- NO MATCH
DllMain -- NO MATCH


Do you now think that the RegExp is correct? How should I solve the
issue now.
Thanks,
Kapil
 
K

Kapil Khosla

perl -pi.bkp -e 's/Main/main/' file.txt

I understand the line above and how it is working but for some reason
on my windows machine, it does not work. Would you know why? Is there
anything else which needs to be done on windows?

Thanks again,
Kapil
 
R

Richard Morse

[some one, I don't know who, wrote:]
That RegExp is far more complicated than it needs to be. You're searching
for: "Word boundary, followed by 'Main', then *optionally* followed by
parenthesized text, followed by end-of-line. Why do you care about the
parentheses and end of line? You said all you wanted to do was replace
"Main" with "main". So the match could just be:

m/\bMain/

I am sorry, I should have been more clear the first time. I want the
RegExp pattern to match
#define Main main - MATCH
int Main() - MATCH
int Main(String * str) - MATCH

but NOT
Mainframe -- NO MATCH
MainMain -- NO MATCH
DllMain -- NO MATCH

Do you now think that the RegExp is correct? How should I solve the
issue now.

So, you want to replace every instance of the _word_ 'Main' with the
word 'main'.

s/\bMain\b/main/g;

HTH,
Ricky
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,002
Messages
2,570,261
Members
46,858
Latest member
FlorrieTuf

Latest Threads

Top