http://qs1969.pair.com?node_id=999883

nvivek has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I want to replace a particular content in my file with some pattern. I planned to use sed with -i option to replace the pattern and make the changes effect in a original file. My sample file content ( test.txt ) : 1 2 3 4 My script is as follows:
use strict; use warnings; system("sed -ie 's/\(.*\)/Number => \1/' test.txt");
When I executed the script, numerals aren't changed to Number => 1. It remains same. Note: When I executed the sed command in shell prompt, it replaced the content of file properly as Number => 1 properly.

Replies are listed 'Best First'.
Re: sed isn't working within a perl script
by Corion (Patriarch) on Oct 19, 2012 at 09:05 UTC

    You will need to modify your string and properly quote the backslash so that it gets passed correctly to the shell. I recommend the following approach:

    use strict; use warnings; my $cmd = "sed -ie 's/\(.*\)/Number => \1/' test.txt"; print "Launching [$cmd]\n"; system($cmd) == 0 or die "Couldn't launch [$cmd]: $! / $?";

    You will see that your single backslashes did not get passed through to the sed command. You will need to double them.

      You're right. Thank you so much. I just doubled the backslashes used in grouping and referring grouped pattern. Then it worked properly. I got confused because I didn't get any error while executing that code.

      Hi,

      is it possible that a backslash gets lost in your solution or simply when posting your solution? I can't see a difference.

      Best regards
      McA

        I did only add the debugging help, not a solution to the problem itself.

        corion posted the original with error checking, so the OP can see/understand what went wrong (how to debug, error check)

        and instructions on how to fix the problem (something for the OP to type)

Re: sed isn't working within a perl script
by Anonymous Monk on Oct 19, 2012 at 09:17 UTC

    :D Calling sed from perl is like driving a bicycle inside a car -- just drive the car

    The perl oneliner equivalent (as s2p helps me understand it)

    perl -i -l -p -e ' s /(.*)/Number => ${1}/s; ' test.txt

    But you still don't want to use system to run that oneliner

    instead use

    use File::Slurp qw/ edit_file /; edit_file { s /(.*)/Number => ${1}/s; } 'test.txt';

    or some such

      You want edit_file_lines because edit_file reads the whole file and not line-by-line
      I don't want to include new module to do this stuff. That's why, I preferred system function with sed command. Reason is I am going to add this stuff in 1000 lines of code which does other operation.
Re: sed isn't working within a perl script
by aitap (Curate) on Oct 19, 2012 at 12:08 UTC

    system("sed -ie 's/\(.*\)/Number => \1/' test.txt");
    See the difference:
    say "sed -ie 's/\(.*\)/Number => \1/' test.txt"; say qq{sed -ie 's/\(.*\)/Number => \1/' test.txt}; say q{sed -ie 's/\(.*\)/Number => \1/' test.txt}; __END__ sed -ie 's/(.*)/Number => /' test.txt sed -ie 's/(.*)/Number => /' test.txt sed -ie 's/\(.*\)/Number => \1/' test.txt
    Double quotes do interpolate your backslashes, and they are lost when you run the command. You need a non-interpolating quote operator instead to pass your string unchanded to the shell.

    And I strongly advice you to use native Perl code instead, too.

    Sorry if my advice was wrong.