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 \
Related
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
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).
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
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
The following is working as expected. I want to replace the word "me" with \'
echo "test ' this" | sed 's/'"'"'/me/g'
test me this
Expected result:
test \' this
Is it possible to escape double quotes as well in the same command?
Your question is a little confusing since there's no me in the original string to replace. However, I think I have it. Let me paraphrase:
I have a sed command which can successfully replace a single quote ' with the word me. I want a similar one which can replace it with the character sequence \'.
If that's the case (you just want to escape single quotes), you can use:
pax$ echo "test ' this" | sed "s/'/\\\'/g"
test \' this
By using double quotes around the sed command, you remove the need to worry about embedded single quotes. You do have to then worry about escaping since the shell will absorb one level of escapes so that sed will see:
s/'/\'/g
which will convert ' into \' as desired.
If you want a way to escape both single and double quotes with a single sed, it's probably easiest to provide multiple commands to sed so you can use the alternate quotes:
pax$ echo "Single '" 'and double "'
Single ' and double "
pax$ echo "Single '" 'and double "' | sed -e "s/'/\\\'/g" -e 's/"/\\"/g'
Single \' and double \"
If I've misunderstood your requirements, a few examples might help.
I have some doubts about your question, but anyway maybe my solution is useful for anyone.
Let's me say before all :
\\ that's mean one \ because when you put two together you are cancelling its meaning as metacharacter. And \x27 as single quote, at least for me is easier than working with single a double ...
Finally I put
echo "test me this" | sed 's/me/\\\x27/g'
so here you have test me ==> test \' this
echo "test \' this" | sed 's/\\\x27/me/g'
and here is the opposite.
Is this what you mean?:
# cat <<! | sed 's/["'"'"']/\\&/g'
> quote '
> double quotes "
> quote ' double quotes "
> !
quote \'
double quotes \"
quote \' double quotes \"
Or this:
# echo "test me test"|sed 's/me/\\'"'"'/g'
test \' test
# echo "test me test"|sed 's/me/\\"/g'
test \" test
I find it best to always single quote sed/awk/perl... commands on the command line and make "holes" for double quote parameters used within them.
I needed to use ' in a script to create a dnsmasq config file, this is the technique I used:
echo -e "\toption name *$name*"|sed s/*/\'/g
example output
option name 'GarageDoor'