2

I'm using the following script, but getting unexpected output.

perl -pi -e '/DB_CHARSET/ and $_.="define('SOMETHING'/, true);\n"' file.txt

This command adds define(SOMETHING, true);

Since the text starts with ' then have " inside, how do I escape 'SOMETHING so that I end up with define('SOMETHING', true)?

I've tried usual \ and it did not help.

4
  • 3
    Of course this is a shell escape problem, not a Perl problem. A silly solution to smuggling in a single quote is to switch quotation styles to "'" for the single quote, then switch back: $ perl -E 'say '"'"'As far as the Perl interpreter knows, this string is single quoted'"'"
    – LSpice
    Oct 29 '20 at 16:25
  • 4
    @LSpice, it's the use of a single-quoted string in the shell command line that makes passing the ' an issue, but it can be solved in the shell or in Perl.
    – ilkkachu
    Oct 29 '20 at 17:19
  • It's important to mention that you want the single quote as a string, not interpreted as perl. Because if the function in question was going to be perl, we could use the quote-like operators q or qq : perl -pi -e '/DB_CHARSET/ and $_.=qq{define(q{SOMETHING}/, true);\n}' file.txt
    – Joe
    Oct 29 '20 at 18:00
10

You could use e.g. \x27 in the Perl string (the character code for ' in hex):

$ perl -e 'print "foo\x27bar"' -l
foo'bar

or handle the quoting in the shell so as to give Perl a raw ':

$ perl -e 'print "foo'\''bar"' -l
foo'bar

(First ' ends the quoted string, \' inserts the quote, the third ' starts a new quoted string.)

1
  • 1
    In addition to '\'' some shells have a setting that allow the use of '' to put an apostrophe into a single quoted string. (In zsh this behavior can be enabled with the command setopt RC_QUOTES, and disabled again with setopt NO_RC_QUOTES.) Maybe something similar exists for your shell?) with such a setting enabled one could write the above command as: perl -e 'print "foo''bar"' -l
    – zrajm
    Oct 29 '20 at 16:25
5

You can change every ' to '\''. But that will get ugly soon.

A better idea is to use a here-document for your script:

perl -pi - <<'EOT' file.txt
/DB_CHARSET/ and $_.="define('SOMETHING'/, true);\n"
EOT

Notice the quotes around EOT. If the here-document terminator is not in (single or double) quotes, $-starting variables, arithmetic substitutions, backticks, etc will be expanded within the here-document. This is a bit different from here-documents in perl, where only single quotes will prevent variable expansions.

2

One way is to use the -s to turn on rudimentary switch processing on the perl commandline and thence define a single quote there:

$ perl -spi -e '$_  .= qq/define(${q}SOMETHING$q, true);/' -- -q=\'   file 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.