If only more languages supported quote operators like Perl. They really do make certain things like this so much easier.<p>Non interpolating quotes:<p><pre><code> q/I wasn't surprised when he said "boo" and game me $5/;
q@I wasn't surprised when he said "boo" and game me $5@;
q!I wasn't surprised when he said "boo" and game me $5!;
q(I wasn't surprised when he said "boo" and game me $5);
q[I wasn't surprised when he said "boo" and game me $5];
</code></pre>
Interpolating quotes:<p><pre><code> qq/Hello, $name!/;
qq!Hello, $name\!!;
qq@Hello, $name!@;
qq(Hello, $name!);
qq[Hello, $name!];
qq'Hello, $name!';
</code></pre>
Rule of thumb, single q for single quote string (non-interpolating normally), and two q's for a double quote string (normally interpolates).
Cool trick!<p>Adding an additional :p modifier prevents the complaint about command not found:<p><pre><code> $ # This string 'has single' "and double" quotes and a $
$ !:q
'# This string '\''has single'\'' "and double" quotes and a $'
# This string 'has single' "and double" quotes and a $: command not found
$
$ # This string 'has single' "and double" quotes and a $
$ !:q:p
'# This string '\''has single'\'' "and double" quotes and a $'
$</code></pre>
Even better -- use this script, paste anything into stdin. It will come back out quotable and pasteable into a shell.<p><pre><code> #!/bin/bash
printf '%q' "$(cat)"
echo</code></pre>
I learned recently that escaping characters in zsh/bash also works for parameter expansion:<p><pre><code> # zsh using flags ${(flags)name}
% string="This is a string with \"\"\" and ''' and \"\" again ''. Also such stuff as & % # ;"
% echo $string
This is a string with """ and ''' and "" again ''. Also such stuff as & % # ;
% echo ${(q)string}
This\ is\ a\ string\ with\ \"\"\"\ and\ \'\'\'\ and\ \"\"\ again\ \'\'.\ Also\ such\ stuff\ as\ \&\ %\ \#\ \;
# bash using operators ${name@operator}
% string="This is a string with \"\"\" and ''' and \"\" again ''. Also such stuff as & % # ;"
% echo $string
This is a string with """ and ''' and "" again ''. Also such stuff as & % # ;
% echo ${string@Q}
'This is a string with """ and '\'''\'''\'' and "" again '\'''\''. Also such stuff as & % # ;'
</code></pre>
Wow, so easy then, I remember struggling so many times in the past when e.g. iterating over filenames with unusual cahracters.<p>/edit: fix markup
One thing I've figured is that in bash you can use $'These kinds of strings', without any variable expansion, but what you get is essentially what's present in most programming languages quote-wise. Example:<p><pre><code> $ echo $'hey there, it\'s "double quotes", \'single quotes\', and some \\, \', ", $ chars'
hey there, it's "double quotes", 'single quotes', and some \, ', ", $ chars</code></pre>
zsh has quote-line by default bound to alt-' which will escape your current command line:<p><pre><code> quote-line (ESC-’) (unbound) (unbound)
Quote the current line; that is, put a ‘’’ character at the beginning and the end, and convert all ‘’’ characters to ‘’\’’’.
</code></pre>
<a href="http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html" rel="nofollow">http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html</a>
Note that you can precede the !:q with `echo` to see the result as well as the invocation without an error.<p><pre><code> $ echo !:q
echo '# This string '\''has single'\'' "and double" quotes
and a $'
# This string 'has single' "and double" quotes and a $</code></pre>
Is anyone else annoyed by the amount of built in magic character strings in bash? There are times where I know a task is possible in a bash script but make it in Python (with no dependencies required and compatible with 2 and 3) because it's easier than looking up every random gotcha and running into issues later on when someone runs it in a directory with a space.
I turned off histexpand because i was fed up with exclamation marks doing random things i never wanted, so this doesn't work for me :(<p>Still, i can use ctur's script approach.
You can always take advantage of what I believe is the portable property of consecutive strings (without space) being concatenated together. Then you never need to escape anything in your scripts.<p>For instance, to produce a double quote inside single quotes, you can do this<p>echo "'"'"'"'"<p>That's three quoted strings next to each other that produce<p>'"'
This works too:<p><pre><code> % cat /tmp/sh
var=variables
x=$(
cat <<EOT
This string has 'single' and "double" quotes and can interpolate '$var'
EOT
)
echo $x
% bash /tmp/sh
This string has 'single' and "double" quotes and can interpolate 'variables'</code></pre>
I wrote bash function that leverages 'set -x' to get me the quoting in "$@" into a single bash env var say $job or in to a temp file. I use it from time to time -- pretty sure it's not perfect, but it works well enough to be useful. To use it it usually involves an 'eval'.
The only thing that trips me up more on becoming a true grey beard other than regex mastery is how and when to properly quote things in my command line incantations.