How to Replace Single Quoted String With a Variable with sed? [duplicate] - linux

This question already has an answer here:
sed fails with "unknown option to `s'" error [closed]
(1 answer)
Closed 1 year ago.
I'm trying to replace some text in a file as described in title. What i tried:
newdir=/dir/to/my/file
sed -i "s/'MyDir'/${newdir}/g" myconf.conf
The command above gives this error:
unknown option to `s'

The problem is that $newdir contains / characters, so your sed command ends up looking like s/'MyDir'//dir/to/my/file/g, which won't work -- the first / effectively terminates your sed expression, and everything else is garbage.
Fortunately, sed let's you use any character as a delimiter to the s command, so you could write instead:
sed -i "s|'MyDir'|${newdir}|g" myconf.conf

One way to get around the "does my data contain the delimiter" problem is to use shell variable expansion to escape the delimiter character:
sed -i "s|'MyDir'|${newdir//|/\\|}|g" myconf.conf
Demo:
$ newdir="/a/dir/with|a/pipe"
$ sed "s|'MyDir'|${newdir}|g" <<< "this is 'MyDir' here"
sed: 1: "s|'MyDir'|/a/dir/with|a ...": bad flag in substitute command: 'a'
$ sed "s|'MyDir'|${newdir//|/\\|}|g" <<< "this is 'MyDir' here"
this is /a/dir/with|a/pipe here
You can do this with the default slash delimiter, with more escapes
sed -i "s/'MyDir'/${newdir//\//\\\/}/g" myconf.conf

Related

sed search string with special character in a file [duplicate]

This question already has an answer here:
sed fails with "unknown option to `s'" error [closed]
(1 answer)
Closed 3 years ago.
I have to search string in in file searchstring is Ev_SQL_DIR=/dev/mirror/sched/sql
and to be searched in file having content as per below
cat file.txt
Ev_SQL_DIR=/dev/mirror/sched/sql
Ev_TRIG_DIR=/hubdev/mirror/sched/trig
Ev_DB2_ENC_STR={iisenc}lasdbDxMsMFVOJBK0Gsg==
EV_COMPILEOPT=-c -O -fPIC -Wno-deprecated -m64 -mtune=generic -mcmodel=small
I used sed -n '/$searchstring/p' file.txt but it gives below error and I tried to escape also tried to use regex but not able to get it right. any inputs?
sed: -e expression #1, char 24: unknown command: `S'
You should use double quotes ". Otherwise Bash will not replace the variable $searchstring for its content. Also, try to use it as:
$ searchstring="Ev_SQL_DIR=/dev/mirror/sched/sql"
$ sed -n "/${searchstring//\//\\/}/p" file.txt
Ev_SQL_DIR=/dev/mirror/sched/sql
It seems that you must use the /. Using # doesn't work for me as well :s
An alternative to this is to use grep. I think it's better in this case, because you do not have to worry about the slashes.
$ grep "$searchstring" file.txt
Ev_SQL_DIR=/dev/mirror/sched/sql
I usually only use sed when I want to replace something, and grep when I want to retrieve a part of a file or string. Grep also has a regex option (-E).

How to use sed or awk or something similar to replace every odd occurrence of character? [duplicate]

This question already has answers here:
Replace every n'th occurrence in huge line in a loop
(4 answers)
Closed 4 years ago.
I have the following string:
"1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55".
How to use awk, or sed to get
"1.0,2.0,3.0,4.0,5.0,6.0,13.05,24233.55"?
I tried to use
sed 's/,/./g' <<< "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55"
1.0.2.0.3.0.4.0.5.0.6.0.13.05.24233.55
and also
sed 's/,/./2' <<< "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55"
1,0.2,0,3,0,4,0,5,0,6,0,13,05,24233,55
Which replaced the second item only. I need every odd occurrence changed.
For future, what would be the code the replace every odd occurrence of, by . ?
Thanks for your help
With any sed that supports EREs via -E, e.g. GNU sed and OSX/BSD sed:
$ echo "1,0,2,0,3,0,4,0,5,0,6,0,13,05,24233,55" | sed -E 's/,([^,]+(,|$))/.\1/g'
1.0,2.0,3.0,4.0,5.0,6.0,13.05,24233.55
The above was inspired by #PesaThe's comment to my original answer.
try this:
for the end:
sed 's/[,]$/?/' YourFile
putting the , between [] allow you to remove most of the regex behavior taking litteral value (not for some char like ^ that need to be manage another way
putting the $ is telling to refere to end of string
the g in your test mean change every occurence, you only wanted 1 and at the end
for the internal:
sed -e 's/,/./1;p' \
-e ':a' \
-e 's/^\(\([^.]*[.][^,]*,\)*\)\([^,]*\),\([^,]*\)/\1\3.\4/
/[^,]*,[^,.]*,/ ta' YourFile
you need a loop and a special test due to alternance existing

How to use sed 's/$var/$var2' file [duplicate]

This question already has an answer here:
sed fails with "unknown option to `s'" error [closed]
(1 answer)
Closed 5 years ago.
I'm trying to replace a value shown as a variable with another value shown as a second variable, using the following line:
sed -i "s/$header/$new/" file.f
Where "$header" is the old variable I want replaced with the new one ($new).
I'm getting this error:
sed: -e expression #1, char 20: unknown option to `s'
I've tried
sed -i 's/$header/$new/' file.f
sed -i "s/$header/$new/" file.f
sed -i 's/"$header"/"$new"/' file.f
None of it seem to work.
How should I write this line so I can get the right output (replacing '$header' with '$new' on the file)?
Thanks in advance
sed -i "s/$old/$new/" file
works fine. You can change the separtor if your data has the character /.
sed -i "s#$old#$new#" file
If you are not sure of the content of the variables and to reduce clashing the separator you can use
sed "s^A$old^A$new^A"
to enter the CTRL-A press CTRL-V + CTRL-A (or any other value not expected in vars)

Insert variable in specific place using sed -i [duplicate]

This question already has answers here:
How to use variables in a command in sed?
(4 answers)
Closed 6 years ago.
i would insert two variable in sed command:
sed -i '39,41 s/^#//' file
i would
sed -i '$LINE,$LINE_INCREMENTED s/^#//' file
but return this:
sed: -e expression #1, char 9: unknown command: `$'
Shell variables are not expanded when put inside single quotes, they are treated literally then.
Do:
sed -i "$LINE,$LINE_INCREMENTED"' s/^#//' file
Assuming the variables only contain digits.
As s/^#// part does not contain any shell expansion, putting double quotes over the full expression would do too, better readability:
sed -i "$LINE,$LINE_INCREMENTED s/^#//" file
drop the quotes for double quotes so environment variables are evaluated:
sed -i "$LINE,$LINE_INCREMENTED s/^#//" file

sed is replacing matched text with output of another command, but that command's output contains expansion characters [duplicate]

This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 6 years ago.
I'm trying to replace text in a file with the output of another command. Unfortunately, the outputted text contains characters bash expands. For example, I'm running the following script to change the file (somestring references output that would break the sed command):
#!/bin/bash
somestring='$6$sPnfj/lnXwZVrec7$fCnL9uy1oWIMZduInKTHBAxhsQxGCsBpm2XfVFFqDPHKidrd93yfjbYvKgYexXHVcvkKdu9lbfy16Ek5GvKy/1'
sed '0,/^title/s/^title*/'"$somestring"'\n&/' $HOME/example.txt
sed fails with this error:
sed: -e expression #1, char 30: unknown option to `s'
I think bash is substuting the contents of $somestring when building the sed command, but is then trying to expand the resulting text. I can't put the entire sed script in single quotes, I need bash to expand it the first time, just not the second. Any suggestions? Thanks
here the forward slash / is the problem. If it's the only issue you can set sed to use a different delimiter.
for example
$ somestring="abc/def"; echo xxx | sed 's/xxx/'"$somestring"'/'
sed: -e expression #1, char 11: unknown option to `s'
$ somestring="abc/def"; echo xxx | sed 's_xxx_'"$somestring"'_'
abc/def
you also need to worry about & and \ chars and escape them if can appear in the replacement text.
If you can't control the the replacement string, either you have to sanitize with another sed script or, alternatively use r command to read it from a file. For example,
$ seq 5 | sed -e '/3/{r replace' -e 'd}'
1
2
3slashes///1ampersand&and2backslashes\\end
4
5
where
$ cat replace
3slashes///1ampersand&and2backslashes\\end
You have several errors here:
the string somestring has characters that are significative for sed command (the most important being '/' that you are using as a delimiter) You can escape it, by substituting it with a previous
somestring=$(echo "$somestring" | sed -e 's/\//\\\//g')
that will convert your / chars to \/ sequences.
you are using sed '0,/^title/s/^title*/'"$somestring"'\n&/' $HOME/example.txt which is looking to substitute the string titl followed by any number of e characters by that $somestring value, followed by a new line and the original one. Unfortunately, sed(1) doesn't allow you to use newline characters in the pattern substitution side of the s command, but you can afford the result by using the i command with a text consisting of you pattern (preceding any new line by a \ to interpret it as literal):
Finally the script leads to:
#!/bin/bash
somestring='$6$sPnfj/lnXwZVrec7$fCnL9uy1oWIMZduInKTHBAxhsQxGCsBpm2XfVFFqDPHKidrd93yfjbYvKgYexXHVcvkKdu9lbfy16Ek5GvKy/1'
somestring=$(echo "$somestring" | sed -e 's/\//\\\//g')
sed '/^title/i\
'"$somestring\\
" $HOME/example.txt
If your shell is Bash, you can use parameter substitution to replace the problematic /:
somestring="{somestring//\//\\/}"
That looks scary, but is easier to understand if you look at the version that replaces x with __:
somestring="${somestring//x/__}"
It might be easier to use (say) underscore as the delimiter for your sed s command, and then the substitution above would be
somestring="${somestring//_/\\_}"
If you already have backslashes, you'll need to first replace those:
somestring="${somestring//\\/\\\\}"
somestring="{somestring//\//\\/}"
If there were other characters that needed escaping (e.g. on the search side of s///), then you could extend the above appropriately.
This URL provides the cleanest answer:
Command to escape a string in bash
printf "%q" "$someVariable"
will escape any characters you need escaped for you.

Resources