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

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

Related

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

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

How to use sed to replace text with a file path? [duplicate]

This question already has answers here:
How to pass a variable containing slashes to sed
(7 answers)
Closed 2 years ago.
I'm writing a bash script where I need to replace text in a file with a specific file path, but my understanding is that sed does not work with specific characters such as /. I'm wondering if there is some way around this?
Here is my script currently:
currentdir="$PWD"
filepathvar="${currentdir}/settings.ini"
sed -i -e "s/filepath/$filepathvar/g" aimparmstest
When I print out filepathvar everything is as I expect it to be, but it seems the fact that filepathvar contains special characters, it gives me the following error:
sed: -e expression #1, char 13: unknown option to `s'
Is there any way around this? Or perhaps another command I can use? I haven't had any success with changing around the parameters. Any help is greatly appreciated.
You can use any character as the separator (the first character). For example:
echo "a/b/c" | sed -e 's|/|_|g'
In your case:
sed -i -e "s|filepath|$filepathvar|g" aimparmstest

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)

Sed expression with escape sequence [duplicate]

This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 6 years ago.
I need to replace the string '../lib' to '/usr/share/server/bootstrap/lib' in a file bootstrap.sh
I used the following sed expression
sed -i -e 's//././/lib///user//share//server//bootstrap//lib/g' bootstrap.sh
It fails with the log
sed: -e expression #1, char 6: unknown option to `s'
Unable to identity the mistake in the expression.Kindly help.
You need to escape every . and /
sed -i -e "s/\.\.\/lib/\/usr\/share\/server\/bootstrap\/lib/" bootstrap.sh
Alternative way to avoid two many backslashes using # as delimiter instead of /.
Thanks sp asic
sed -i "s#../libs#/usr/share/server/bootstrap/lib#" bootstrap.sh

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