I'm trying to:
sed -i s/installpath/"$INSTALL_PATH"/ /tmp/myscript.conf
when $INSTALL_PATH is just a string everything works. but if install path is an actual path (II guess the '/' char is the problem) like /home/ubuntu/install_script. then It breaks with the following error message:
sed: -e expression #1, char 16: unknown option to `s'
btw: I tried without the "" around $INSTALL_PATH. didn't work
Thanks for the help!
It is likely that $INSTALL_PATH contains slashes, which means that they will be interpreted by sed as part of the s/pattern/replacement/ construct. To avoid this, you should use a different separator, for example ~:
sed -i "s~installpath~$INSTALL_PATH~" /tmp/myscript.conf
I have also wrapped the whole sed line in quotes rather than quoting one section. In general, it's a good idea to do this as it prevents other characters from being interpreted by the shell. Normally single quotes are used but if shell variables are to be expanded, use double quotes.
You don't have to use / as the delimiter in sed commands. Use something that's less likely to occur in a filename, e.g.:
sed -i s^installpath^"$INSTALL_PATH"^ /tmp/myscript.conf
If you're careful with quoting you can use other characters which are even less likely to exist inside a filename:
sed -i "s|installpath|$INSTALL_PATH|" /tmp/myscript.conf
The pipe is outright illegal in Windows paths, and on Linux it's a really bad idea and unlikely to occur in the wild.
Related
I have 2 bash script variables defined:
THELINENUMBER="14" # an arbitrary line number, comes from a separate command
NEWLINE="a line/ with# special! characters<" # arbitrary line with special characters, comes from separate command
I need to use the line number ${THELINENUMBER} to replace a line in a file called after.txt with ${NEWLINE}.
How do I do that?
These are some examples I have tried:
sed -i '${THELINENUMBER}s#.*#"/"${NEWLINE}"/"' after.txt
sed -i "${THELINENUMBER}s#.*#"/"${NEWLINE}"/"" after.txt
sed -i "${THELINENUMBER}s/.*/'${NEWLINE}'" after.txt
sed -i '${THELINENUMBER}s,.*,${NEWLINE}' after.txt
I am told that the delimitter is usually a /, but those are present in my line replacement variable, so I can't use those. I tried with # and , but the desired behavior did not change. I am also told that " and ' are supposed to be used to turn off escaping in text (use literal string), but I have not been able to get that to work either. How do I pass in a string parameter into sed that has special characters? I am wondering if I should pass the variable ${NEWLINE} into another built-in function call to add escape characters or something before passing it into sed. Is sed the right tool for the job? I did not find much helpful information looking at the CLI manpages. I use Ubuntu 18.04.
I have referred to these sources in my internet search:
https://stackoverflow.com/questions/11145270/how-to-replace-an-entire-line-in-a-text-file-by-line-number
https://askubuntu.com/questions/76808/how-do-i-use-variables-in-a-sed-command
https://stackoverflow.com/questions/37372047/find-a-line-with-a-string-and-replace-entire-line-with-another-line
Use the c (change) command.
By the way, the naming convention for regular shell variables is NOT ALLCAPS, as that may result in accidental collisions with special variables like PATH.
sed "$linenumber c\\
$newline" file
Try
sed -i "${THELINENUMBER}s#.*#${NEWLINE}#" after.txt
this works because:
You require " enclosing the entire sed command instead of backtick so that the variables are expanded
No other quotes or backticks are needed to escape " in the variables as there aren't any: there are no literal (escaped) quotes inside the variables
An alternate separator (such as #) is required due to the / inside the NEWLINE variable.
this is perhaps one of the most discussed topics here. I tried almost all the commands and other tweaks found here, but something doesn't seems to be doing well.
i would want to replace all the double quotes in my file with whitespace/blank
I'm seeing the below error when i tried to execute this command.
sed "s/"/ \''/g' x_orbit.txt > new.tx
sed: -e expression #1, char 3: unterminated `s' command
You're close. Just use single quotes, so the shell doesn't try to expand the metacharacters in your sed command:
sed 's/"/ /g' x_orbit.txt > new.txt
You could try tr for example:
tr '"' ' ' < x_orbit.txt > new.txt
The script you provided:
sed "s/"/ \''/g' x_orbit.txt > new.tx
means:
sed # invoke sed to execute the following script:
" # enclose the script in double quotes rather than single so the shell can
# interpret it (e.g. to expand variables like $HOME) before sed gets to
# interpret the result of that expansion
s/ # replace what follows until the next /
" # exit the double quotes so the shell can now not only expand variables
# but can now do globbing and file name expansion on wildcards like foo*
/ # end the definition of the regexp you want to replace so it is null since
# after the shell expansion there was no text for sed to read between
# this / and the previous one (the 2 regexp delimiters)
\' # provide a blank then an escaped single quote for the shell to interpret for some reason
'/g' # enclose the /g in single quotes as all scripts should be quoted by default.
That is so far off the correct syntax it's kinda shocking which is why I dissected it above to try to help you understand what you wrote so you'll see why it doesn't work. Where did you get the idea to write it that way (or to put it another way - what did you think each character in that script meant? I'm asking as it indicates a fundamental misunderstanding of how quoting and escaping works in shell so it'd be good if we could help correct that misunderstanding rather than just correct that script.
When you use any script or string in shell, simply always enclose it in single quotes:
sed 'script' file
var='string'
unless you NEED to use double quotes to let a variable expand and then use double quotes unless you NEED to use no quotes to let globbing and file name expansion happen.
An awk version:
awk '{gsub(/"/," ")}1' file
gsub is used for the replace
1 is always true, so line is printed
I want to replace <lexicon uri="file://C:/image/png/grammars/custom/image-custom.lex?SWI.type=backup"/><lexicon uri="file://C:/image/jpg/grammars/custom/image-dot-custom.lex?SWI.type=backup"/> with null in multiple files.
The code is given below.
sed -i s|<lexicon uri="file://C:/image/png/grammars/custom/image-custom.lex?SWI.type=backup"/><lexicon uri="file://C:/image/jpg/grammars/custom/image-dot-custom.lex?SWI.type=backup"/>||g *
Here I am getting this error:
< was unexpected at this time.
Please clarify for me what is not working here.
Could you please try following and let me know if this helps you. By using # as sed's separator you need not to escape / in it only need to escape ., ? not to take their special meaning
sed -E 's#<lexicon uri="file://C:/image/png/grammars/custom/image-custom\.lex\?SWI\.type=backup"/><lexicon uri="file://C:/image/jpg/grammars/custom/image-dot-custom\.lex\?SWI\.type=backup"/>##' Input_file
Tested it with:
sed --version
GNU sed version 4.2.1
works with #
sed -i -e 's#<lexicon uri="file://C:/image/png/grammars/custom/image-custom.lex?SWI.type=backup"/><lexicon uri="file://C:/image/jpg/grammars/custom/image-dot-custom.lex?SWI.type=backup"/>##g' test.txt
The pattern contains shell metacharacters, which need to be quoted or escaped. Usually, in Bash, you should use single quotes around strings, unless you need the shell to interpolate variables and command substitutions and interpret backslash sequences (in which case use double quotes) or to also perform whitespace tokenization and wildcard expansion (in which case use no quotes). See also When to wrap quotes around a shell variable?
sed -i 's|<lexicon uri="file://C:/image/png/grammars/custom/image-custom.lex?SWI.type=backup"/><lexicon uri="file://C:/image/jpg/grammars/custom/image-dot-custom.lex?SWI.type=backup"/>||' *
I also took out the g flag, which only makes sense if you expect multiple matches within a single line. (Perhaps you do after all, in which case obviously put it back.)
I'm writing a script to replace dafault configuration values to user specified ones. But i'm getting unterminated 's' command errors from sed. After 2 Hours of googling i still haven't figured out whats causing this. The lines are:
CONFIG_GMETAD_COMPUTENODES="scccompute1 scccompute2"
CONFIG_GMETAD="/etc/gmetad.conf"
sed -i 's/localhost/'${CONFIG_GMETAD_COMPUTENODES}'/g' ${CONFIG_GMETAD}
this substitutes to
sed -i 's/localhost/scccompute1 scccompute2/g' /etc/gmetad.conf
error i get
sed: -e expression #1, char 23: unterminated `s' command
I don't see whats wrong in here, but haven't worked quite often with sed.
You need to quote your variables. Note how the sed command expands:
sed -i 's/localhost/'scccompute1 scccompute2'/g' /etc/gmetad.conf
This creates multiple options, not a single one with your sed script. Instead, try:
sed -i 's/localhost/'"${CONFIG_GMETAD_COMPUTENODES}"'/g' "${CONFIG_GMETAD}"
Containing the variable within double quotes causes the whole string to be treated as a single argument to sed, which is what you want. And of course, quotes around the filename because the filename might contain special characters. As a rule, always quote variables when you refer to them in bash.
Note that if the embedded variable contains slashes or some other special characters, it may break your script. So you might want to do some sanity checking before feeding it to sed:
CONFIG_GMETAD_COMPUTENODES="${CONFIG_GMETAD_COMPUTENODES//[^a-z0-9 ]/}"
This will strip all characters that are not alphanumeric or space, if bash is your shell.
The problem come from quoting in bash.
You should use
sed -i "s/localhost/${CONFIG_GMETAD_COMPUTENODES}/g"
I believe this may be a simple question, but I've looked everywhere and tried some workarounds, but I still haven't solved the problem.
Problem description:
I have to replace a character inside a file and I can do it easily using the command line:
sed -e 's/pattern1/pattern2/g' full_path_to_file/file
But when I use the same line inside a bash script I can't seem to be able to replace it, and I don't get an error message, just the file contents without the substitution.
#!/bin/sh
VAR1="patter1"
VAR2="patter2"
VAR3="full_path_to_file"
sed -e 's/${VAR1}/${VAR2}/g' ${VAR3}
Any help would be appreciated.
Thank you very much for your time.
Try
sed -e "s/${VAR1}/${VAR2}/g" ${VAR3}
Bash reference says:
The characters ‘$’ and ‘`’ retain their special meaning within double quotes
Thus it will be able to resolve your variables
I use a script like yours... and mine works as well!
#!/bin/sh
var1='pattern1'
var2='pattern2'
sed -i "s&$var1&$var2&g" *.html
See that, mine use "-i"... and the seperator character "&" I use is different as yours.
The separator character "&" can be used any other character that DOES NOT HAVE AT PATTERN.
You can use:
sed -i "s#$var1#$var2#g" *.html
sed -i "s#$var1#$var2#g" *.html
...
If my pattern is: "test#email.com" of course you must use a seperator different like "#", "%"... ok?