How to escape single quote in sed? - sed

How to escape a single quote in a sed expression that is already surrounded by quotes?
For example:
sed 's/ones/one's/' <<< 'ones thing'

Quote sed codes with double quotes:
$ sed "s/ones/one's/"<<<"ones thing"
one's thing
I don't like escaping codes with hundreds of backslashes – hurts my eyes. Usually I do in this way:
$ sed 's/ones/one\x27s/'<<<"ones thing"
one's thing

One trick is to use shell string concatenation of adjacent strings and escape the embedded quote using shell escaping:
sed 's/ones/two'\''s/' <<< 'ones thing'
two's thing
There are 3 strings in the sed expression, which the shell then stitches together:
sed 's/ones/two'
\'
's/'

Escaping single quote in sed: 3 different ways:
From fragile to solid...
Note: This answer is based on GNU sed!!
1. Using double-quotes to enclose sed script:
Simpliest way:
sed "s/ones/one's/" <<< 'ones thing'
But using double-quote lead to shell variables expansion and backslashes to be considered as shell escape before running sed.
1.1. Specific case without space and special chars
In this specific case, you could avoid enclosing at shell level (command line):
sed s/ones/one\'s/ <<<'ones thing'
will work until whole sedscript don't contain spaces, semicolons, special characters and so on... (fragile!)
2. Using octal or hexadecimal representation:
This way is simple and efficient, if not as readable as next one.
sed 's/ones/one\o047s/' <<< 'ones thing'
sed 's/ones/one\x27s/' <<< 'ones thing'
And as following character (s) is not a digit, you coul write octal with only 2 digits:
sed 's/ones/one\o47s/' <<< 'ones thing'
3. Creating a dedicated sed script
cat <<eosedscript >sampleSedWithQuotes.sed
#!$(which sed) -f
s/ones/one's/;
eosedscript
chmod +x sampleSedWithQuotes.sed
From there, you could run:
./sampleSedWithQuotes.sed <<<'ones thing'
one's thing
This is the strongest and simpliest solution as your script is the most readable:$ cat sampleSedWithQuotes.sed
#!/bin/sed -f
s/ones/one's/;
3.1 You coud use -i sed flag:
As this script use sed in shebang, you could use sed flags on command line. For editing file.txt in place, with the -i flag:
echo >file.txt 'ones thing'
./sampleSedWithQuotes.sed -i file.txt
cat file.txt
one's thing
3.2 Mixing quotes AND double quotes
Using dedicated script may simplify mixing quotes and double quotes in same script.
Adding a new operation in our script to enclose the word thing in double quotes:
echo >>sampleSedWithQuotes.sed 's/\bthing\b/"&"/;'
( now our script look like:
#!/bin/sed -f
s/ones/one's/;
s/\bthing\b/"&"/;
)
then
./sampleSedWithQuotes.sed <<<'ones thing'
one's "thing"

The best way is to use $'some string with \' quotes \''
eg:
sed $'s/ones/two\'s/' <<< 'ones thing'

Just use double quotes on the outside of the sed command.
$ sed "s/ones/one's/" <<< 'ones thing'
one's thing
It works with files too.
$ echo 'ones thing' > testfile
$ sed -i "s/ones/one's/" testfile
$ cat testfile
one's thing
If you have single and double quotes inside the string, that's ok too. Just escape the double quotes.
For example, this file contains a string with both single and double quotes. I'll use sed to add a single quote and remove some double quotes.
$ cat testfile
"it's more than ones thing"
$ sed -i "s/\"it's more than ones thing\"/it's more than one's thing/" testfile
$ cat testfile
it's more than one's thing

This is kind of absurd but I couldn't get \' in sed 's/ones/one\'s/' to work. I was looking this up to make a shell script that will automatically add import 'hammerjs'; to my src/main.ts file with Angular.
What I did get to work is this:
apost=\'
sed -i '' '/environments/a\
import '$apost'hammerjs'$apost';' src/main.ts
So for the example above, it would be:
apost=\'
sed 's/ones/one'$apost's/'
I have no idea why \' wouldn't work by itself, but there it is.

Some escapes on AppleMacOSX terminals fail so:
sed 's|ones|one'$(echo -e "\x27")'s|1' <<<'ones thing'

use an alternative string seperator like ":" to avoid confusion with different slashes
sed "s:ones:one's:" <<< 'ones thing'
or if you wish to highligh the single quote
sed "s:ones:one\'s:" <<< 'ones thing'
both return
one's thing

Related

How to add quote at the end of line by SED

sed -i 's/$/\'/g'
sed -i "s/$/\'/g"
How to escape both $ and ' by 1 command?
This might work for you (GNU sed):
sed 's/$/'\''/' file
Adds a single quote to the end of a line.
sed 's/\$/'\''/' file
Replaces a $ by a single quote.
sed 's/\$$/'\''/' file
Replaces a $ at the end of line by a single quote.
N.B. Surrounding sed commands by double quotes is fine for some interpolation but may return unexpected results.
Use octal values
sed 's/$/\o47/'
Care to use backslash + letter o minus + octal number 1 to 3 digit
Just don't use single quotes to start the sed script?
sed "s/$/'/"
The /g at the end means to apply everywhere it's found on each stream (line) - you don't need this since $ is a special character indicating end of stream.
To add a quote at the end of a line use
sed -i "s/$/'/g" file
sed -i 's/$/'"'"'/g' file
See proof.
If there are already single quotes, and you want to make sure there is single occurrence at the end of string use
sed -i "s/'*$/'/g" file
sed -i 's/'"'*"'$/'"'"'/g' file
See this proof.
To escape $ and ' chars use
sed -i "s/[\$']/\\\\&/g" file
See proof
[\$'] - matches $ (escaped as in double quotes it can be treated as a variable interpolation char) or '
\\\\& - a backslash (need 4, that is literal 2 backslashes, it is special in the replacement), and & is the whole match.

Need to parse the following sed command: sed -e 's/ /\'$'\n/g'

I stumble upon the command sed -e 's/ /\'$'\n/g'that supposedly takes an input and split all spaces into new lines. Still, I don't quite get how the '$' works in the command. I know that s stands for substitute, / / stands for the blank spac, \n stands for new line and /g is for global replacement, but not sure how \'$' fits in the picture. Anybody who can shed some light here will be much appreciated.
Basically it's meant for platform portability. With GNU sed it would be just
sed -e 's/ /\n/g'
because GNU sed is able to interpret \n as new line.
However, other versions of sed, like the BSD version (that comes with MacOS) do not interprete \n as newline.
That's why the command is build out of two parts
sed -e 's/ /\' part2: $'\n/g'
The $'\n/g' is an ANSI C string parsed by the shell before executing sed. Escape sequences like \n will get expanded in such strings. Doing so, the author of the command passed a literal new line (0xa) to the sed command rather than passing the escape sequence \n. (0x5c 0x6e).
One more thing, since the newline (0xa) is a command separator in sed, it needs to get escaped. That's why the \ at the end of the first part.
Alternatively you could just use a multiline version:
sed -e 's/ /\
/g'
Btw, I would have written the command like
sed -e 's/ /\'$'\n''/g'
meaning just putting the $'\n' into the ANSI C string. Imo that's better to understand.

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).

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 \