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?
Related
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 learning bash and I'm trying to parse a webpage(https://chromium-i18n.appspot.com/ssl-address) and extract the href o
f interest using sed. The pattern I'm using is:
/<a\shref=\'\/ssl-address\/data\/([^\"]*)\'>/siU
However, I cant get the expression to work with sed. When i run:
data=$(wget ${serviceUrl} -q -O -)
parsedData=$(sed '/<a\shref=\'\''\/ssl-address\/data\/([^\"]*)\'\''>/siU/' <<< ${data})
echo ${parsedData}
I get the following error:
sed: 1: "/<a\shref=\'\/ssl-addre ...": unterminated substitute pattern
What am I doing wrong?
Is this what you're trying to do?
$ wget 'https://chromium-i18n.appspot.com/ssl-address' -q -O - |
sed -n 's:.*/ssl-address/data/\([^'\'']*\).*:\1:p'
AC
AD
AD/Canillo
AD/Encamp
I see you're getting some answers using double quotes instead of single around your sed script so you can do "...'..." instead of '...'\''...' - though tempting and it'd function OK for this particular current example, don't do it. To avoid any surprises now or if/when your requirements change later, in all shell programming always enclose strings and scripts in single quotes unless you need to expose them to the shell for interpretation and then use double quotes unless you need the shell to do globbing and file name expansion on them and then use no quotes.
All right, you are trying to parse an entire webpage.
This situation require to delete all the lines you don't need.
As #Ed Morton said, you can use something else than sed.
Your webpage is this as you told us in a comment, so you first need do download it.
Note that the changing how you download the source of the page, you can change some thing (E.G. copy pasting it from the console of Firefox you will have href=", using wget you will have href=').
That said, let's use wget as you are currently doing in your question.
# This will create the ssl-address file
wget "https://chromium-i18n.appspot.com/ssl-address"
# This will give you a list of all of the links in a href.
sed -e "/<a href='.*/! d" -e "s/<a href='\/ssl-address\/data\/\(.*\)'.*/\1/" ssl-address
EDIT:
Reading your comments I saw you would like to filter some of the output (E.G. deleting all the examples link)
This can be done adding a piece of sed in order to delete lines you don't need.
In your case you just need to add -e "/<a href='\/ssl-address\/examples.*/d" so the whole line of code should be as follow:
sed -e "/<a href='.*/! d" -e "/<a href='\/ssl-address\/examples.*/d" -e "s/<a href='\/ssl-address\/data\/\(.*\)'.*/\1/" ssl-address
You probably want something like this, based on that input data:
sed -e "s/.*href='\([^']*\)'.*/\1/"
It says, "match anything .* followed by the literal characters href=' followed by anything other than the ' character [^']* (we capture using the \( ... \) notation) followed by the ' character followed by anything".
Note I used the " to enclose the sed expression, to avoid you having to quote the '.
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'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.
I am trying to replace a line in a file with the value of a variable (the variable contains a windows path). Although the variable prints correctly to STDOUT, when used in sed to replace the line of interest, the backslashes disappear.
Any idea how to remedy this? Other ideas welcome.
CODE:
WINPATH="\\\\hd-place\\stor1\\fold1\\archive\\$VAR1.$Var2\\Viewer"
print this to screen (as it should): \\hd-place\stor1\fold1\archive\$VAR1.$Var2\Viewer
The SED command I'm using is: cat file.xml | sed "3 c\
<\RunFolder>$WINPATH</RunFolder>" (please excuse the slashes inside the XML tags)
This outputs this:
\hd-placestor1fold1archive$VAR1.$Var2Viewer
Where as I want this:
\\hd-place\stor1\fold1\archive\$VAR1.$Var2\Viewer
You need one additional layer of escapes for the backslashes, as sed also interprets them after the variable has been expanded.