Search and replace a string in files

Discussion in 'Perl Misc' started by Kapil Khosla, Apr 4, 2004.

  1. Kapil Khosla

    Kapil Khosla Guest

    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
     
    Kapil Khosla, Apr 4, 2004
    #1
    1. Advertising

  2. Kapil Khosla

    Henry Law Guest

    On 3 Apr 2004 22:41:03 -0800, (Kapil Khosla)
    wrote:

    >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
     
    Henry Law, Apr 4, 2004
    #2
    1. Advertising

  3. Kapil Khosla

    Paul Lalli Guest

    On Sun, 3 Apr 2004, Kapil Khosla wrote:

    > 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
     
    Paul Lalli, Apr 4, 2004
    #3
  4. Kapil Khosla

    Paul Lalli Guest

    On Sun, 4 Apr 2004, Henry Law wrote:

    > On 3 Apr 2004 22:41:03 -0800, (Kapil Khosla)
    > wrote:
    >
    > >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.
    >


    So would a good Perl programmer. :)

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


    Paul Lalli
     
    Paul Lalli, Apr 4, 2004
    #4
  5. (Kapil Khosla) wrote in message news:<>...
    > 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.
     
    Himanshu Garg, Apr 4, 2004
    #5
  6. Paul Lalli <> wrote:
    > On Sun, 4 Apr 2004, Henry Law wrote:
    >> On 3 Apr 2004 22:41:03 -0800, (Kapil Khosla)
    >> wrote:
    >>
    >> >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.
    >>

    >
    > 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"? ...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 4, 2004
    #6
  7. Kapil Khosla <> wrote:

    > 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?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 4, 2004
    #7
  8. Kapil Khosla

    Kapil Khosla Guest

    > 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





    >
    >
    > > }
    > > }
    > >
    > > #################
    > >
    > > 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
     
    Kapil Khosla, Apr 4, 2004
    #8
  9. Kapil Khosla

    Kapil Khosla Guest

    >
    > 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
     
    Kapil Khosla, Apr 4, 2004
    #9
  10. In article <>,
    (Kapil Khosla) wrote:

    > [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

    --
    Pukku
     
    Richard Morse, Apr 7, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luke Dalessandro
    Replies:
    1
    Views:
    705
    Luke Dalessandro
    Dec 23, 2004
  2. Rolf Kemper
    Replies:
    0
    Views:
    402
    Rolf Kemper
    Dec 23, 2004
  3. RajaniKumarV
    Replies:
    0
    Views:
    461
    RajaniKumarV
    Feb 22, 2010
  4. Trans
    Replies:
    2
    Views:
    111
    William James
    Apr 22, 2006
  5. sharath
    Replies:
    11
    Views:
    206
    Ross Bamford
    May 24, 2006
Loading...

Share This Page