I am trying to use sed to replace &
by \&
in a tex file.
I'm using sed -i "s/ & / \\\& /g" bibfile.bib;
However, the result in the file is \ &
and not \&
as I expect.
Any help would be welcome,
Marc

- 544,893

- 21
-
Related: Number of backslashes needed for escaping regex backslash on the command-line – steeldriver Dec 02 '22 at 13:37
-
Using double quotes means you have only extra layer of escaping to do for backslash. Use single quotes instead (assuming you're using a Bourne-like shell). – Stéphane Chazelas Dec 02 '22 at 13:40
1 Answers
In Bourne-like shells, using double quotes means you have one extra layer of escaping to do for backslash as \
is used inside double quotes to escape `
, "
, $
and itself and do line continuation.
Use single quotes instead.
There are also more shells that support '...'
as a quoting operator than some supporting "..."
.
So:
sed -i 's/ & / \\\& /g' bibfile.bib
calls sed
with sed
, -i
, s/ & / \\\& /g
¹ and bibfile.bib
as four separate arguments.
To send the same arguments using double quotes, you'd need at least:
sed -i "s/ & / \\\\\&" bibfile.bib
Where the first two pairs of \
become one \
each and \&
stays \&
.
sed -i "s/ & / \\\\\\&" bibfile.bib
Would also work and be cleaner IMO making it more explicit that you want 3 backslashes to be passed to sed
, each inserted as \\
within double quotes.
You could also do:
sed -i 's/ \(& \)/ \\\1/g' bibfile.bib
Or:
sed -Ei 's/ (& )/ \\\1/g' bibfile.bib
Your:
sed -i 's/ & / \\\& /g' bibfile.bib
Actually passes sed
, -i
, s/ & / \\& /g
and bibfile.bib
as argument to sed
, which it interprets as prefixing each " & "
with " \"
and suffixing with " "
.
For completeness, in some other shells:
csh/tcsh
in csh/tcsh, \
is not special within '...'
nor "..."
(except to escape !
for history expansion).
So sed -i "s/ & / \\\& /g" bibfile.bib
and sed -i 's/ & / \\\& /g' bibfile.bib
would both work there.
fish
In fish, \
is also special inside '...'
, so you'd need either:
sed -i "s/ & / \\\\\\& /g" bibfile.bib
Or
sed -i 's/ & / \\\\\\& /g' bibfile.bib
The latter still preferred in the general case as there are fewer characters to escape within.
rc
rc has only one form of quoting: '...'
(not "..."
, nor \
nor $'...'
nor $"..."
)
sed -i 's/ & / \\\& /g' bibfile.bib
only there.
See How to use a special character as a normal one in Unix shells? for more details as to what characters are special and how to escape/quote them in various shells.
¹ and for sed
, in the replacement part of its s/pattern/replacement/flags
command, the \\
is interpreted as a backslash and \&
as a literal &
as opposed to its special meaning of expanding to what was matched.

- 544,893