sed replace with backslash, double quote, single quote - sed

Can you give the sed command that will find \" and replace with \\' in a file.
For example line:
LOG_FN=\"file_name\"
will become
LOG_FN=\\'file_name\\'
By using this template:
sed -i 's/old-text/new-text/g' input.txt
I tried following sed commands:
sed -i 's/\\\"/\\\\\'/g' input.txt
sed -i "s/\\\"/\\\\'/g" input.txt
Unfortunately they fail because what I am looking for is a string substitution for \" while commands I tried change individual " characters.

You can't escape a single quote inside single quotes. Your second attempt needs more backslashes: Remember, inside double quotes, the shell processes one layer of backslashes, so you have to double each backslash which should make it through to sed.
sed "s/\\\\\"/\\\\\\\\'/g" input.txt
After the shell has processed the double-quoted string, the script which ends up being executed is
s/\\"/\\\\'/g
where the first pair of backslashes produce a literal backslash in the matching regex, and each pair of backslashes in the replacement produce one literal backslash in the output.
Demo: https://ideone.com/XqfwbV

Related

sed replace using string containing backslashes

I need to replace text in a file with a Windows-style directory path containing backslash (REVERSE SOLIDUS) characters. I am already using an alternative expression delimiter. The backslashes appear to be treated as escape characters.
How can I keep the backslashes in the output?
$ echo DIR=foobar | sed -e "s#DIR=.*#$(cygpath -w $(pwd))#"
C:gwin64homelit
The desired output is:
C:\cygwin64\home\lit
You'll have to escape metacharacters in sed replacement pattern. Fortunately, there are only three of those: &, \, and a delimiter / (see this question and this). In your case, since you're using # for delimiter, you'll have to escape # instead of /.
You can create a helper shell function (like here):
escapeSubst() { sed 's/[&#\]/\\&/g'; }
and then pass your string through it before giving it to sed, like this:
$ echo DIR=foobar | sed -e "s#DIR=.*#$(cygpath -w $(pwd) | escapeSubst)#"
C:\cygwin64\home\lit

Escape backslash character in sed

I need to modify some Windows paths.
For instance,
D:\usr
to
D:\first\usr
So, I have created a variable.
$path = "first\usr"
then used the following command:
sed -i -e 's!\\usr!${path}/g;' test.txt
However, this ends up with the following:
D:\firstSr
How do I escape \u in sed?
Assuming your path variable was assigned properly (without spaces in the assignment: path='first\usr'), fixing step by step for an input file test.txt with one example path:
$ cat test.txt
D:\usr
Your original command
$ sed 's!\\usr!${path}/g;' test.txt
sed: -e expression #1, char 18: unterminated `s' command
doesn't do much, as you've mixed ! and / as the delimiter.
Fixing delimiters:
$ sed 's!\\usr!${path}!g;' test.txt
D:${path}
Now no interpolation happens at all because of the single quotes. I suspect these are just copy-paste mistakes, as you obviously got some output.
Double quotes:
$ sed "s!\\usr!${path}!g" test.txt
bash: !\\usr!${path}!g: event not found
Now this clashes with history expansion. We could escape the !, or use a different delimiter.
/ as delimiter:
$ sed "s/\\usr/${path}/g" test.txt
D:\firstSr
Now we're where the question actually started. ${path} expands to first\usr, but \u has a special meaning in GNU sed in the replacement string: it uppercases the following character, hence the S.
Even without the special meaning, \u would most likely just expand to u and the backslash would be gone.
Escaping the backslash:
$ path='first\\usr'
$ sed "s/\\usr/${path}/g" test.txt
D:\first\usr
This works.
Depending on which shell you are using, you may be able to use parameter expansion to double \ in your substitution string and prevent the \u interpretation:
path="first\usr"
sed -e "s/\\usr/${path//\\/\\\\}/g" <<< "D:\usr"
The syntax for replacing a pattern with the shell parameter expansion is ${parameter/pattern/string} (one replacement) or ${parameter//pattern/string} (replace all matches).
This substitution is not specified by POSIX, but is available in Bash.
Where it is not available, you may need to filter $path through a process:
path=$(echo "$path" | sed 's/[][\\*.%$]/\\&/g')
(N.B. I have also quoted other sed metacharacters in this filter).

how to replace a \' with '' using sed

I have a file like this test.sql:
'here is' and \' other for 'you'
and would like to replace the \' (escaped single quote) with '' (2 singles quotes) for postgres and leave other single quotes alone. How would I do this. I have tried:
Mon Mar 16$ sed -i.bak s/\'/''/g test.sql
but this takes out all the single quotes.
Your enemy in this is shell quoting. The string
s/\'/''/g
is mangled by the shell before it is given to sed. For the shell, '' is an empty string, and \' suppresses this special meaning of single quotes (so that the quote is an actual single quote character). What sed sees after processing is
s/'//g
...wich just removes all single quotes.
There are several ways to work around the problem; one of them is
sed -i.bak "s/\\\\'/''/g" test.sql
Inside the doubly-quoted shell string, backslashes need to be escaped (exceptions exist). This means that "s/\\\\'/''/g" in the shell command translates to s/\\'/''/g as argument to sed. In sed regexes, backslashes also need escaping, so this is, in fact, what we wanted to happen: All instances of \' will be replaced with ''.
sed "s/[\\]'/''/g" test.sql
# also work but may depend on shell
sed "s/[\]'/''/g" test.sql
same idea as Wintermute but using class to avoig multi escaping for shell than sed in double quote

Substitute with backslash in sed

I want to replace word with \word{sth} with sed.
I type in
sed -i s#word#\\word{sth}
but i am getting is word{sth} instead of \word{sth}
I tried with 1 slash also in the command
you should add four backslashes.
you need two to escape the backslash by the terminal, and two to escape it for sed. 2*2=4.
$ echo word|sed s#word#\\\\word{sth}#gi
\word{sth}
Consider enclosing sed expression with single-quotes '
sed -i 's#word#\\word{sth}#' file

Escaping single quotes

I want to replace the double quotes in the sed command in the following example with single quotes.
set new_string to do shell script "echo " & quoted form of list_string & " | sed -e 's/$/\"/' -e 's/^/\"/' -e 's/^/+/'"
However if I replace the double quotes with single quotes I get an error, is there a way to escape single quotes?
I'm no sed ninja, so any hints on how to go about this is highly appreciated.
if you want to replace " with ' using sed:
sed 's/"/\x27/g' yourFile
\x27 - single
\x22 - double
it could make code looks cleaner, and with less escape.
see the test:
kent$ cat quote.tmp
""""""
kent$ sed 's/"/\x27/g' quote.tmp
''''''
fYou had a quotation fault. Just to replace double quotes for single quotes, this is enough
set list_string to "This program said: \"Hello World!\""
set new_string to do shell script "/bin/echo -n " & quoted form of list_string & " | sed -e 's/\"/'\\''/g'"
Explaining 's/\"/'\''/g'
The \\ and \" is needed in the applescript environment and will be in the shell just \ and ". So what's entering the shell is 's/"/'\''/g'. Then what's with all the quotes? A very common mistake is thinking that quotations on the command line works the same as in programming. A single quote turns substitution on or off. So the first single quote turns substitution off which mean the next characters will be interpreted as text and has no special meanings (including the escape character). So to escape a single quote we'll need to turn the substitution on, then we can escape a single quote and turn the substitution off again.
You need to be careful about which quotes are being parsed by sed and which are being parsed by the environment invoking sed. Normal invocations of sed come from shell scripts, but (based on your tag) it appears that you're calling it from an AppleScript.
From a shell script you would say
| sed -e 's/$/'\''/' -e 's/^/'\''/' -e 's/^/+/'
But I don't know if sh-style escaping rules are in effect for you or whether you need to additionally escape the \