Good-day,
In a Bash shell script I'm putting together, I am trying to find this text: /usr/local/freeswitch/log/freeswitch.log and replace it with: /var/log/freeswitch/freeswitch.log in this file: /etc/fail2ban/jail.local
This is what I have tried so far, both of which result in the error: sed: -e expression #1, char 75: unterminated `s' command
Attempt #1
sed -i 's~usr/local/freeswitch/log/freeswitch.log~var/log/freeswitch/freeswitch.log' /etc/fail2ban/jail.local
Attempt #2
sed -i 's~usr/local/freeswitch/log/freeswitch.log/var/log/freeswitch/freeswitch.log' /etc/fail2ban/jail.local
My research shows that since the text I'm searching for includes the "/" character, I should be using a different delimiter "~" to separate the find and replace strings. But looks like I'm doing something wrong, any assistance would be appreciated, thanks.
The structure of a sed substitution command is s/PATTERN/REPLACEMENT/ (note the delimiter at the end of the command).
You're right, you can change the delimiter to a different character, so if you're going to use ~ you need to put one of those at the end of the command.
Related
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.
I have a problem with sed. I want to replace the entire specific line number for multiple lines in multiples documents.
This the bash command for 1 specific line in 1 specific document:
BNAME=$(basename $FILE .pdb)
psfgen1="pdb ./sedpdb/${BNAME}.pdb/"
sed -i '8s/'.*'/'${psfgen1}'/' ./psfgen.inp
And I get this error :
sed: -e expression #1, char 60: unterminated `s' command
Is anyone know how to solve this issue? Thanks!
I can see two things wrong:
There are forward slashes in the string that you're attempting to use in the sed command. These will be interpreted as part of the command, so you should use a different delimiter.
The * is unquoted, so will be glob-expanded by the shell to the names of all the files in the directory.
Reliably using shell variables in string substitutions is non-trivial but can be done using one of the approaches shown in the answers to this question.
In your case, it looks like you can probably get away with using another character as the delimiter, such as #:
sed -i "8s#.*#${psfgen1}#" ./psfgen.inp
I am trying to substitute a word using sed with two words. For example I'm using:
sed s/TITLE/New Title/ old.txt > new.txt
However, when I run the command the following populates:
sed: -e expression #1, char 17: unterminated `s' command
Any help would be of great appreciation. I've searched everywhere without any clarity.
You are missing quotes. You need to wrap the substitution portion inside quotes like:
sed 's/TITLE/New Title/' old.txt > new.txt
If you are using variables as part of substitution, you'll need to use double quotes " instead of single quotes ' to allow variables to interpolate.
Take a look at sed man page and explore -i option which allows you to make in-place changes.
I need to replace a string with another string in a file.
i have the below line a file.
tibco.env.LD_LIBRARY_PATH %TPCL_HOME%/lib/httpclient_3.0:%TPC
L_HOME%/lib:%RV_HOME%/lib:%TRA_HOME%/icjava/6.2/lib:%LD_LIBRARY_PATH%
i need to replace "tibco.env.LD_LIBRARY_PATH " with
"tibco.env.LD_LIBRARY_PATH %RV_HOME%/lib/64:"
and finally the line should be
tibco.env.LD_LIBRARY_PATH %RV_HOME%/lib/64:%TPCL_HOME%/lib/httpclient_3.0:%TPC
L_HOME%/lib:%RV_HOME%/lib:%TRA_HOME%/icjava/6.2/lib:%LD_LIBRARY_PATH%
i tried with the below command but getting error sed: -e expression #1, char 66: unknown option to `s'
sed -i s/"tibco.env.LD_LIBRARY_PATH "/"tibco.env.LD_LIBRARY_PATH %RV_HOME%/lib/64:"/ bwengine.tra
can someone help in fixing the issue.
If the pattern you want to replace or the replacement string contain the slash, use a different separator, e.g. =:
s="tibco.env.LD_LIBRARY_PATH "="tibco.env.LD_LIBRARY_PATH %RV_HOME%/lib/64:=
you may think to use & as the matched string which will reduce the length of the sed command.
sed 's!tibco.env.LD_LIBRARY_PATH !&%RV_HOME%/lib/64:!' file
refer this url: http://www.grymoire.com/unix/Sed.html#uh-3
I'm trying to add some text (a path) at the end of a line which is found by a sed command:
var="/folder1/folder2/folder3"
sed -i "/Begins with this text/s/$/$var/" filename
I know that double quotes are needed to use variables in a sed command but if I use the above command it gives me an error message saying:
expresssion #1, character 23: unknown option to `s
What am I doing wrong?
Change the delimiter in the substitute command to something that won't appear in $var, e.g.
sed -i "/Begins with this text/s|$|$var|" filename
or escape the slashes in $var:
var="\/folder1\/folder2\/folder3"