Replace a word that has a specific format with another format - linux

I want to replace the space between c and 2 ('C 2',) with two spaces as 'C 2', I tried with sed -i but it does not work
sed -i 's/'C 2',/'C 2',/g' test.dat

The quotes stop the quoting. Either change the quoting or escape it.
You could do it like so:
sed -i 's/'\''C 2'\'',/'\''C 2'\'',/g' test.dat
The '\'' stop the quoting, escape a single quote and then continue with quoting.
But for your specific case, you could just use double quotes:
sed -i "s/'C 2',/'C 2',/g" test.dat

Related

Why do sed a and sed s commands behave differently with respect to escape characters under single quotes and double quotes?

I know there are differences between single quotes and double quotes in a sed expression, but I didn't know there are differences between sed a and sed s expressions.
For sed s expressions, \t is translated as a tab correctly both in single and double quotes. \\t also does the same thing in double quotes.
# '\t' works for single quotes
$ echo -e "abc\n123" | sed 's|abc|&\n\tdef|'
abc
def
123
# '\\t' fails for single quotes
$ echo -e "abc\n123" | sed 's|abc|&\\n\\tdef|'
abc\n\tdef
123
# '\t' works for double quotes
$ echo -e "abc\n123" | sed "s|abc|&\n\tdef|"
abc
def
123
# '\\t' also works for double quotes
$ echo -e "abc\n123" | sed "s|abc|&\\n\\tdef|"
abc
def
123
However, in sed a expressions, I have to use \\t in a single quotes expression and \\\t in one with double quotes.
# '\t' fails for single quotes
$ echo -e "abc\n123" | sed '/abc/a\tdef'
abc
tdef
123
# '\\t' works for single quotes
$ echo -e "abc\n123" | sed '/abc/a\\tdef'
abc
def
123
# '\t' fails for double quotes
$ echo -e "abc\n123" | sed "/abc/a\tdef"
abc
tdef
123
# '\\t' fails for double quotes
$ echo -e "abc\n123" | sed "/abc/a\\tdef"
abc
tdef
123
# '\\\t' works for double quotes
$ echo -e "abc\n123" | sed "/abc/a\\\tdef"
abc
def
123
I had to change my sed a expressions to sed s ones to unify the outputs due to this phenomenon. Things work perfectly, but I'd like an explanation.
The commands above are executed on Ubuntu 20.04.
sed has no idea which quotes you use. The shell parses and removes the quotes. Inside single quotes, text is preserved completely verbatim; inside double quotes, the shell performs variable substitution, command substitution, and backslash processing. The rules are simple, but sometimes surprising: in brief, a backslash quotes the next character as literal, and so, a pair of backslashes gets translated to a single backslash. However, backslashes in front of characters which do not need escaping are preserved. So for example, \t is equivalent to \\t inside double quotes.
sed for its part performs another round of backslash processing. In some contexts, some versions of sed understand \t to represent a literal tab character, but generally not in the text after the a, c, or i commands.
The actual question here is probably actually about the formatting of the a command. This differs between sed versions, but out of the box on Ubuntu, it simply outputs the literal text after the command. A backslash in this context is just a literal backslash, which again escapes the next character to ensure it is interpreted literally. Unlike the shell, sed simply removes this backslash.
In Bash, you can use $'...' "C-style" strings which let you encode a literal tab symbolically. However, you need to add literal backslashes in a couple of places: sed doesn't accept an unescaped literal newline in the s command, and the tab after a needs a backslash in order for it not to be skipped as insignificant whitespace.
printf '%s\n' abc 123 ghi |
sed -e $'s/abc/&\\\n\tdef/' \
-e $'/ghi/a\\\tjkl'
To reiterate, inside $'...' a \t gets replaced by the shell with a literal tab character, \n with a newline, etc, before the string gets passed on to the command (sed in this case).
In the grand scheme of things, you may be better off using a less haphazard tool than sed for this. Awk is much easier to read, write, and debug.

How to accomodate single quotes in sed bash [duplicate]

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'
I know this is going to sound like a cop out but I could never get sed working when there were both single and double quotes in the string. To help any newbies like me that are having trouble, one option is to split up the string. I had to replace code in over 100 index.hmtl files. The strings had both single and double quotes so I just split up the string and replaced the first block with
<!-- and the second block with -->. It made a mess of my index.html files but it worked.
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

sed command to replace 'root'#'localhost' with 'root'#'%'

I am trying to use sed to replace the expression 'root'#'localhost' with 'root'#'%' with no success. Could someone please help me with the command?
I tried the following:
sed -i ’s#\’root\’#\’localhost\’#\’root\’#\’%\’#g’ xyz.sql
sed: -e expression #1, char 1: unknown command: `?'
sed -i -e ’s/localhost/%/g’ xyz_2616.sql
sed: -e expression #1, char 1: unknown command: `?'
First, make sure you're using a single quote. ’ (a.k.a. ’ or unicode 8217) is not the same as ASCII character 39, '.
Next, you can't escape single quotes inside single quotes. Here's an answer I wrote about that some time ago.
You can, however, put single quotes inside double quotes, or escape them outside your single quoted string. For example, either of the following might work:
sed -e "s/'root'#'localhost'/'root'#'%'/g" file.sql
or
sed -e 's/'\''root'\''#'\''localhost'\''/'\''root'\''#'%'\''/g' file.sql
Alternately, you could substitute just the portion you're interested in, trusting that it doesn't appear elsewhere on the same line:
sed -e '/root.#.localhost/s/localhost/%/' file.sql
The ’ character doesn't look like a single quote (') to me. Make sure that you are using single quotes.
The character you're actually typing is a "right single quote mark". What we refer to as a "single quote" is actually an "apostrophe".
The following should work:
sed -e 's/localhost/%/g' rice_2616.sql
or, your first alternatives but with double quotes to avoid having to escape the embedded single quotes (which I presume are apostrophes):
sed -e "s/'root'#'localhost'/'root’#'%'/g" rice_2616.sql

search and replace string using sed

i have a sed command like this for search and replace string inside a file:
sed -i -e 's/`db1`./`db2`./g' result/files1.sql
that is working fine to replace the db1 to db2 inside the file of: result/files1.sql
however when i change it to bash and variable format, it does not work.
sed -i -e "s/`${mydbname}`./`${mydbname2}`./g" "${mypath}"
i get error like:
./mycoolscript: line 241: db1: command not found
./mycoolscript: line 241: db2: command not found
any solution would be great.
If is something you need to replace, you will need to escape by . Here it is
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Escape the backtick character
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Bash treats the part within backticks as a command and first executes that.
Try this
sed -i -e "s/${mydbname}/${mydbname2}/g" "${mypath}"
There is one more way, of using single quotes for literals & double quotes only around variables/escape sequences.
sed -i -e 's/`'"${mydbname}"'`./`'"${mydbname2}"'`./g' "${mypath}"
Because of single quotes, you will not have to escape the special characters.
The trade-off between escaping special characters vs. using mix of single & double quotes would depend on number of special characters vs. number of variables.
If there are too many characters that would need escaping & less number of variables, I would prefer mix of single & double quotes.

replace old-link-url to new-link-url with sed

I'm writing a script in bash that would replace old-link-url to new-link-url
my problem is that sed can't replace the url because of the slashes. If i put just some text it works.
my code
sed -e s/"$old_link"/"$new_link"/g wget2.html > playlist.txt
sed supports any character as separator, so if the pattern you are trying to replace contains /, use a different separator. Most commonly used are # and |
sed 's|foo|bar|g' input
sed 's#foo#bar#g' input
Don't forget to put double quotes if you are using variables in sed substitution. Also, if your variable have / then use a different delimiter for sed. You can use _, %, |, # and many more.
So may be something like this would work -
sed -e "s_"$old_link"_"$new_link"_g" wget2.html > playlist.txt

Resources