I am trying to use this command:
sed -i 's#\{test1\}#test2#' /example/myfile.txt
To replace instances of {test1} with test2.
I get the error:
sed: -e expression #1, char 17: Invalid preceding regular expression
Am I not escaping the curly braces correctly?
sed -i 's#{test1}#test2#' /example/myfile.txt
You don't need escape {}
You aren't escaping the curly braces at all. In sed, the default regular expressions are BREs, where \{ and \} indicate a range expression. Since test1 isn't a range, your BRE is incorrect.
To fix it, you can either drop the backslashes (braces aren't special in BREs) or keep it the same and tell sed to use EREs (-r flag with GNU sed, -E flag with BSD/MacOSX sed).
Related
I need to modify some Windows paths.
For instance,
D:\usr
to
D:\first\usr
So, I have created a variable.
$path = "first\usr"
then used the following command:
sed -i -e 's!\\usr!${path}/g;' test.txt
However, this ends up with the following:
D:\firstSr
How do I escape \u in sed?
Assuming your path variable was assigned properly (without spaces in the assignment: path='first\usr'), fixing step by step for an input file test.txt with one example path:
$ cat test.txt
D:\usr
Your original command
$ sed 's!\\usr!${path}/g;' test.txt
sed: -e expression #1, char 18: unterminated `s' command
doesn't do much, as you've mixed ! and / as the delimiter.
Fixing delimiters:
$ sed 's!\\usr!${path}!g;' test.txt
D:${path}
Now no interpolation happens at all because of the single quotes. I suspect these are just copy-paste mistakes, as you obviously got some output.
Double quotes:
$ sed "s!\\usr!${path}!g" test.txt
bash: !\\usr!${path}!g: event not found
Now this clashes with history expansion. We could escape the !, or use a different delimiter.
/ as delimiter:
$ sed "s/\\usr/${path}/g" test.txt
D:\firstSr
Now we're where the question actually started. ${path} expands to first\usr, but \u has a special meaning in GNU sed in the replacement string: it uppercases the following character, hence the S.
Even without the special meaning, \u would most likely just expand to u and the backslash would be gone.
Escaping the backslash:
$ path='first\\usr'
$ sed "s/\\usr/${path}/g" test.txt
D:\first\usr
This works.
Depending on which shell you are using, you may be able to use parameter expansion to double \ in your substitution string and prevent the \u interpretation:
path="first\usr"
sed -e "s/\\usr/${path//\\/\\\\}/g" <<< "D:\usr"
The syntax for replacing a pattern with the shell parameter expansion is ${parameter/pattern/string} (one replacement) or ${parameter//pattern/string} (replace all matches).
This substitution is not specified by POSIX, but is available in Bash.
Where it is not available, you may need to filter $path through a process:
path=$(echo "$path" | sed 's/[][\\*.%$]/\\&/g')
(N.B. I have also quoted other sed metacharacters in this filter).
I want to replace word with \word{sth} with sed.
I type in
sed -i s#word#\\word{sth}
but i am getting is word{sth} instead of \word{sth}
I tried with 1 slash also in the command
you should add four backslashes.
you need two to escape the backslash by the terminal, and two to escape it for sed. 2*2=4.
$ echo word|sed s#word#\\\\word{sth}#gi
\word{sth}
Consider enclosing sed expression with single-quotes '
sed -i 's#word#\\word{sth}#' file
I have a makefile that contains this command:
sed '/^$/d'
when I ran it I got:
sed '/^d'
sed: -e expression #1, char 3: unterminated address regex
looks like it interprets the dollar sign, how can I prevent that from happening?
You have to double all dollar signs in a recipe, otherwise make treats them as introducing a make variable:
sed '/^$$/d'
If you search for "dollar sign makefile" or similar you'll find tens if not hundreds of answers to virtually this exact question.
Use $$, it becomes $. See Special Characters in a Makefile
Makefile:
sed '/^$$/d'
learts#Fastidio:~/tmp$ make
sed '/^$/d'
I have a config file I need to change (again) and the line is
set wrapper_code=C:\windows\drivers\cache
I need to change it to
set wrapper_code=/home/harry/solo/run
I wrote
cat Proxy.bat | sed -i.bk -e 's/\(^set wrapper_home\=\).*/\/home/'1${dbuser}'/gateway/service\' Proxy.bat
I get an error message
sed: -e expression #1, char 37: unknown option to `s'
What is wrong with my code string
If you are using / as the pattern separator is sed, you have to escape the slashes in the strings (paths). To avoid it, use a different separator:
sed -i.bk -e 's%\^set wrapper_code=C:\\windows\\drivers\\cache%set wrapper_code=/home/harry/solo/run%' Proxy.bat
You also have to escape backslashes, as they have a special meaning in sed.
The cat part is useless.
I'd like to replace all the \r\n with < br/ >in a document, and I'm trying this see script below
# sed -i 's/\r\n/<br/>' ~/xxd/*
however i got this error back
sed: -e expression #1, char 12: unknown option to `s'
How do i solve this problem?
Thanks!
Your problem is that you have the / separator in your replacement string so sed is assuming that's the end of your replacement, and that the > following it is a flag.
If your sed is modern enough, just use a different separator character, one that's not in the replacement string:
pax$ echo hello | sed -e 's/e/<br />/'
sed: -e expression #1, char 9: unknown option to `s'
pax$ echo hello | sed -e 's?e?<br />?'
h<br />llo
Alternatively, you can escape the offending character but I try to avoid that since it tends to lead to overly sawtooth sed commands like /\/\/\/\/\/\.
The other thing you may want to watch out for is trying to use \n in your regex since sed operates on lines anyway. If your intent is to just strip carriage returns and insert HTML line breaks, then the following sed command may be better:
s?\r$?<br />?