11

E. g. I want to say

perl -e 'print '"'"'Hello, world!'"'"', "\n";'

Is there a less awkward way to do it, e. g. escaping single-quotes?

Yes, I know that I can write

perl -e 'print q[Hello, world!], "\n"'
perl -e 'print "Hello, world!\n"'

But this question is about quoting in the shell, not in the Perl.

I'm interested how to do it in bash and csh in the first place.

6 Answers 6

10

Dennis points out the usual alternatives in his answer (single-in-double, double-in-single, single quoted strings concatenated with escaped single quotes; you already mentioned Perl's customizable quote operators), but maybe this is the direct answer you were looking for.

In Bourne-like shells (sh, ksh, ash, dash, bash, zsh, etc.) single quoted strings are completely literal. This makes it easy to include characters that the shell would otherwise treat specially without having to escape them, but it does mean that the single quote character itself can not be included in single quoted strings.

I refuse to even think about the csh-type shells since they are utterly broken in other regards (see Csh Programming Considered Harmful).

5
  • Thank you. "This is impossible" - it is the answer that I expected :) Though I always hoped that it is here documents that are dedicated to play this role.
    – codeholic
    Mar 1, 2010 at 15:21
  • Unlike in Perl, Bourne-like shell here documents are only directly useful for providing input via stdin. You can, of course, put single quotes in them. You can also enable "literal mode" of a here document by quoting the word: (e.g.) blah <<\EOF … EOF. You can also use <<'EOF' and <<"EOF. They all mean literal here documents (unlike Perl). If you were really determined, you could do blah "$(cat<<\EOF … EOF )" other args (using newlines where I have written spaces in the command substitution; ksh and zsh can do without the cat, the others need it). But would it really be worth it? Mar 1, 2010 at 21:16
  • Just want to note that zsh single quotes are not quite literal. Zsh will try to interpret a '\U' anywhere in a single-quoted string as a character code, e.g. echo '\U0000068\U000069' echoes 'hi'. Not sure why though unless it's a bug in the shell.
    – Matthew
    Jul 10, 2013 at 18:47
  • 1
    @Matthew: The interpretation of \U in that case is being done by built-in echo command (this behavior can be controlled by -E or the BSD_ECHO option and -e). You can see that the literal string is passed (and not otherwise interpreted) in other commands; e.g. printf %s\\n '\U0000068\U000069'. Jul 10, 2013 at 18:59
  • @ChrisJohnsen Thanks, I'm new to zsh and didn't realize this but you're right. The man page told me -e is default but zsh must override that.
    – Matthew
    Jul 10, 2013 at 22:10
5

For me, all your examples produce:

Hello, world!

And so does this:

perl -e 'print "Hello, world!", "\n";'

And this:

perl -e 'print '\''Hello, world!'\'', "\n";'

Can you clarify what it is you're trying to do?

In the shell, such as Bash, if you want to print quotation marks as part of the string, one type of quotes escapes the other.

$ echo '"Hello, world!"'
"Hello, world!"
$ echo "'Hello, world!'"
'Hello, world!'

Edit:

Here's another way:

$ perl -e 'print "\047Hello, world!\047", "\n";'
'Hello, world!'
$ echo -e "\047Hello, world! \047"
'Hello, world! '

The space after the exclamation point avoids a history expansion error. I could have done set +H instead.

1

Not sure if my edit to the previous answer would show up:

Pasting the same as a new answer:

Alternate approach:

When i tried your solution i could still not get the ' printed.

But i took cue from your solution and tried the following:

$ perl -e '$foo = chr(39); print "${foo}Hello, world ${foo}", "\n";'
'Hello, world '

ASCII value of ' is 39.

I needed this to make an inline edit to bunch of files to add ' at a location of interest.

1

Here document is the best way to not care about escaping:

$ cat <<EOF
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

You may completely inibit all expantion by using quoted here document:

$ cat <<'EOF'
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

If you want to pass it as argument instead of input, you can use xargs:

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF
1

I don't know if there's an option to do this in bash, but with zsh you can use '' after turning on the RC_QUOTES option. (I would recommend trying zsh; it's mostly bash-compatible and can emulate bash for even more compatibility.)

With bash (and still most of the time with zsh), I just use '\'' because it's easier to read than '"'"'.

I have absolutely no idea how to do it in csh.

-2

You can use \' and \" to escape quotes with perl if used internally as part of a perl script. I'm not sure if the command line will accept that though. You could try it and see if it works.

1
  • 3
    If it were so easy, I wouldn't ask. You could try it and see if it works before posting an answer.
    – codeholic
    Mar 1, 2010 at 7:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .