Usually, in order to embed a quotation mark in a string, \
(backslash) is used.
Does a backslash have a different meaning in a Bash script?
My code below isn't working: the quotation mark wasn't included, and the following errors were reported:
recursive_merge.sh: line 7: unexpected EOF while looking for matching `''
recursive_merge.sh: line 14: syntax error: unexpected end of file
I have no explanation. Line 14 doesn't even exist.
#!/bin/bash
#############this file should be in the directory directly upper than p0x. sphnum.txt should also be at the same directory
for i in 02 03 04 05 06 07 09 10 11 12 13 14 15 16 17 20 21 22 23 24 25; do
x=$(grep $i sphnum.txt |cut -c5-6)
y=$(grep $i sphnum.txt |cut -c8-9)
z=$(echo '\''$i'.ala.r'$x'.sph '$i'.ala.r'$y'.sph\'')
w=$(echo $i'.ala.r'$x'r'$y'.sph')
echo $z
echo $w
cd p$i/spheres.10_2_75/sph/
/project/Biogroup/Software/Docking/MergeSpheres.pl -s $z -o $w -n 500 &
cd ../../../
done
As tripleee points out in comments on the question, the best approach in this particular scenario is to use a double-quoted string, in which you can embed both variable references (e.g., $i
) and single quotes as-is; e.g.: z="'$i.ala.r$x.sph $i .ala.r$y.sph'"
This answer focuses on the various approaches to producing / embedding literal '
chars. in strings, starting with the OP's misconception.
Your use of '\''
suggests that you're confused by the workaround that is commonly used to "embed" a single quote in an overall single-quoted string, which is not what your code does on the z=...
line, because it starts with '\''
.
If we simplify your command, we get:
echo '\''$i
which is a syntax error, because to Bash the single quotes are unbalanced, because '\'
by itself is considered a complete single-quoted string containing literal \
, followed by the opening '
of a second single-quoted string, which is never closed.
Again it's worth noting that "'$i"
is the best solution to this specific problem: the '
can be embedded as-is, and including variable reference $i
inside the double-quoted string protects its value from potentially unwanted word-splitting and filename expansion (globbing).
POSIX-like shells provide NO way to embed single quotes inside a single-quoted string - not even with escaping. Hence, the \
in '\'
is simply treated as a literal (see below for a workaround).
The rest of this answer shows all approaches to producing a literal '
, both inside and outside quoted strings.
To create a single quotation mark outside of a quoted string, simply use \'
:
$ echo I am 6\' tall.
I am 6' tall.
This quotes (escapes) the individual '
character only, using \
.
But note that tokens placed outside the context of a single- or double-quoted string on a command line are subject to word-splitting and filename expansion (globbing).
To use a single quote inside a double-quoted string, use it as-is (no escaping needed):
$ echo "I am 6' tall."
I am 6' tall.
This is the best choice if you also want to embed variable references (e.g., $i
) or commands (via command substitutions, $(...)
) in your string (you can suppress interpolation by escaping $
as \$
).
To use a single quote inside a single-quoted string (in which no interpolations (expansions) are performed by design), you must use a workaround:
$ echo 'I am 6'\'' tall.'
I am 6' tall.
The workaround is necessitated by single-quoted strings not supporting embedded single quotes at all; the '\''
part only makes sense "inside" a single-quoted string in that:
'
terminates the single-quoted string so far\'
then produces a '
literal individually escaped with \
outside the context of a quoted string.'
then "restarts" the remainder of the single-quoted string.In other words: While you cannot directly embed a single quote, you can break the single-quoted string into multiple pieces, insert individually \
-escaped '
instances outside the single-quoted string as needed, and let Bash's string concatenation (which automatically joins directly adjacent string) piece it all back together to form a single string.
chepner points out in a comment that you can alternatively use a here-document with a quoted opening delimiter, which acts like a single-quoted string while allowing embedding of '
chars:
read -r var <<'EOF' # quoted delimiter -> like a '...' string, but ' can be embedded
I am 6' tall.
EOF
With an unquoted opening delimiter, the here-document acts like a double-quoted string, which, just like the latter, also allows embedding '
, while also supporting expansions:
read -r var <<EOF # unquoted delimiter -> like a "..." string
$USER is 6' tall.
EOF
Finally, if remaining POSIX-compliant is not a must, you can use an ANSI C-quoted string string, which allows embedding single quotes with \'
;
note that such strings interpret control-character escape sequences such as \n
, but otherwise, like a normal single-quoted string, do not perform interpolation of variable references or command substitutions:
$ echo $'I am 6\' tall.'
I am 6' tall.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With