How to escape the ampersand character while using sed - shell

I want to replace all single quotes in a string with two single quotes using sed. But when the string contains the & character, the sed command is not replacing single quotes that come after that. How can I escape the & character so that the single quotes after it are still replaced?

You don't need to escape anything in the input:
$ echo "123 ' foo & b'ar" | sed "s/'/''/g"
123 '' foo & b''ar
However, in the 'replacement' part of the s command & has a special meaning: it means 'match'. That's why the above command can be re-written as:
$ echo "123 ' foo & b'ar" | sed "s/'/&&/g"
123 '' foo & b''ar
Escape it with a \ like everything else that needs to be escaped, if needed:
$ echo "123 ' foo & b'ar" | sed "s/'/'\&'/g"
123 '&' foo & b'&'ar

It's easier to answer if you post your code, but I'm guessing you're not escaping the ampersand. Change & to \& if you want a literal ampersand.
See section 3.1.2 of The sed FAQ for a more detailed explantion, if you're curious.

It's working for me
bash>echo "'This is a string with 'single quote' & '&'" | sed "s/'/''/g"
''This is a string with ''single quote'' & ''&''

Related

escape " double quotes" and slash (/) while variable substitution in sed

I want to escape "" and / for my VAR.
InFile contains below variable
var_value='"skdskdlskdlskjdlsdjsld/jshdks00=="'
Echo ${var_value}
"skdskdlskdlskjdlsdjsld/jshdks00=="
While substitution i do not want / and ""
I tried
sed "s#JWT=<<CHANGE_ME>>#"${JWT}"#g" InFile > OutFile
Expected OutFile :
JWT=skdskdlskdlskjdlsdjsld/jshdks00==
A help here would be much appreciated
Use
sed 's#JWT=<<CHANGE_ME>>#JWT='"${JWT}"'#g' InFile > OutFile
Here, the concatenation scheme is the following:
's#JWT=<<CHANGE_ME>>#JWT='"${JWT}"'#g'
|------------------------||------||--|
1 2 3
1 - single quoted part
2 - a double quoted string with interpolated variable
3 - single quoted part again.
See the online demo:
#!/bin/bash
JWT="skdskdlskdlskjdlsdjsld/jshdks00=="
sed 's#JWT=<<CHANGE_ME>>#JWT='"${JWT}"'#g' <<< "JWT=<<CHANGE_ME>>"
## => JWT=skdskdlskdlskjdlsdjsld/jshdks00==

Bash String Replacing ""

I'm doing my first bash coding and I have a String like this :
""987653547660485627"",""987653547660485626"",""987653547660485625""
Is there any way to change every iteration of "" into singles to make it look like:
"987653547660485627","987653547660485626","987653547660485625"
I guess you were facing the problem of double-quotes.
You need to escape the double quotes:
kent$ echo $foo
""foo"",""bar""
kent$ echo "${foo//\"\"/\"}"
"foo","bar"
sed can replace string pattern:
orig='""987653547660485627"",""987653547660485626"",""987653547660485625""'
echo $orig | sed 's/""/"/g'
Will yield:
"987653547660485627","987653547660485626","987653547660485625"
The description of the argument to sed is "Replace every instance of "" with ", including multiple times in each row"

tr command: strange behavior with | and \

Let's say I have a file test.txt with contents:
+-foo.bar:2.4
| bar.foo:1.1:test
\| hello.goobye:3.3.3
\|+- baz.yeah:4
I want to use the tr command to delete all instances of the following set of characters:
{' ', '+', '-', '|', '\'}
Done some pretty extensive research on this but found no clear/concise answers.
This is the command that works:
input:
cat test.txt | tr -d "[:blank:]|\\\+-"
output:
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
I experimented with many combinations of that set and I found out that the '-' was being treated as a range indicator (like... [a-z]) and therefore must be put at the end. But I have two main questions:
1) Why must the backslash be double escaped in order to be included in the set?
2) Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Like this:
tr -d '\-|\\+[:blank:] ' < file
You have to escape the - because it is used for denoting ranges of characters like:
tr -d '1-5'
and must therefore being escaped if you mean a literal hyphen. You can also put it at the end. (learned that, thanks! :) )
Furthermore the \ must be escaped when you mean a literal \ because it has a special meaning needed for escape sequences.
The remaining characters must not being escaped.
Why must the \ being doubly escaped in your example?
It's because you are using a "" (double quoted) string to quote the char set. A double quoted string will be interpreted by the shell, a \\ in a double quoted string means a literal \. Try:
echo "\+"
echo "\\+"
echo "\\\+"
To avoid to doubly escape the \ you can just use single quotes as in my example above.
Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Following CharlesDuffy's comment having the | at the end means also that you had the unescaped - not at the end, which means it was describing a range of characters where the actual range depends on the position you had it in the set.
another approach is to define the allowed chars
$ tr -cd '[:alnum:]:.\n' <file
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
or, perhaps delete all the prefix non-word chars
$ sed -E 's/\W+//' file

How to delete double quotes from the beginning and the end of a string

I have strings which contain double quotes like this one:
"[{"clientid":"*", "identityzone":"*"}]"
I would like to use set or grep to delete the double quotes at the beginning and at the end of it, the output should look like :
[{"clientid":"*", "identityzone":"*"}]
I have used : sed -e 's/\"//g' but this deletes all the " in a string
You need to use line anchors
$ echo '"[{"clientid":"*", "identityzone":"*"}]"' | sed 's/^"//; s/"$//'
[{"clientid":"*", "identityzone":"*"}]
^" match " only at start of line
"$ match " only at end of line
You can also combine them using | as sed 's/^"\|"$//g'
See Overview of basic regular expression syntax
easy:
sed 's/^\"\(.*\)\"$/\1/g' <<<'"[{"clientid":"*", "identityzone":"*"}]"'

Add an escape character before comma+space in a file

How do I add an escape character "\" before each ", " in a file? (that's a comma followed by a space).
P.S. Those quotes are for formatting purposes and are not presented (nor should appear in the file).
see this example, if it is helpful for you:
kent$ echo "foo,bar,blah"|sed 's/,/\\,/g'
foo\,bar\,blah
if you want to replace the comma, only if there is a space followed, do this:
kent$ echo "foo, bar, blah,skipme"|sed 's/, /\\&/g'
foo\, bar\, blah,skipme
For each character
put wanted character to escape in a class [ ,] (space and ,in this case`)
echo 'Your, string or data' | sed 's/[, ]/\\&/g'
there is special rules for ], - and \ (see RegEx class documentation for this)
For specifing pattern
echo 'Your, string or data' | sed 's/, /\\&/g'

Resources