-2

I would like to replace single escape char \ with double \ using sed However when I use

`echo $regex | sed 's/\\/\\\\/g'`

it returns sed: -e expression #1, char 8: unterminated `s' command is there a solution for this?

xenofu
  • 1
  • 2
  • Add double quotes around "$regex". Learn how to quote properly in shell, it's very important : > "Double quote" every literal that contains spaces/metacharacters and _every_ expansion: `"$var"`, `"$(command "$var")"`, `"${array[@]}"`, `"a & b"`. Use `'single quotes'` for code or literal `$'s: 'Costs $5 US'`, `ssh host 'echo "$HOSTNAME"'`. See


    – Gilles Quénot Dec 16 '19 at 19:31
  • It [seems to work](https://ideone.com/bGopWp) – Wiktor Stribiżew Dec 16 '19 at 19:32
  • unfortunately it didn't help, `echo "$regex_b" | sed 's/\\/\\\\/g'` still return the same: sed: -e expression #1, char 8: unterminated `s' command – xenofu Dec 16 '19 at 19:36
  • You don't have to use `/` as the `sed` delimiter. `sed 's@/@//@g'` should do the trick. – mpez0 Dec 16 '19 at 19:36
  • tried with it too but didn't work out, seems like sed doesn't catch delimiters when I put these escapes – xenofu Dec 16 '19 at 19:40
  • use $() instead of `` worked, thanks for answers! – xenofu Dec 16 '19 at 19:44
  • With backticks, you have to escape **all** the backslashes: ``echo "`echo "$regex" | sed 's/\\\\/\\\\\\\\/g'`"`` -- a compelling reason to use `$(...)` – glenn jackman Dec 16 '19 at 19:48

2 Answers2

0

I took the commands in the question and ran like so in BASH:

#!/bin/bash

regex='This\is a \ test'
echo $regex
echo $regex | sed 's/\\/\\\\/g'

results=$(echo $regex | sed 's/\\/\\\\/g')
echo $results

This gives me the expected result of \\ for every found backslash. In the last two lines, I stored the output into a variable called $results, which appears to be what was attempted in the question with the backticks.

Jason K Lai
  • 1,500
  • 5
  • 15
0

It seems the backticks are making the escape character get evaluated again before being passed to sed. To get around that, double up how often they get escaped.

`echo $regex | sed 's/\\\\/\\\\\\\\/g'`

Your original rendition would have worked fine if you had not used backticks.

echo $regex | sed 's/\\/\\\\/g'

And this would have worked fine if you had encapsulated it within $() instead of backticks (as described in another answer).

As noted in comments, if this is part of a script where you are building a pattern to be used elsewhere, there is likely a weakness in your approach if you need this kind of manipulation.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • The backticks are either an artifact of the question or a problem in and of themselves. Nothing about the name `regex` suggests that the result of the substitution is a command to execute. – chepner Dec 16 '19 at 19:43
  • @chepner: You are saying the OP should clarify why backticks are involved at all. I agree. – jxh Dec 16 '19 at 19:45
  • I need to put this to variable so that's why I use ``, but your answer or using $() is solution here – xenofu Dec 16 '19 at 19:49
  • @xenofu So your command is actually something like ``foo=`echo $regex | ...` ``? – chepner Dec 16 '19 at 19:54