How can I uncomment a line // Configure::write('debug', 2); using sed? I've tried
sed 's+// Configure::write('debug', 2);+Configure::write('debug', 2);+g' -I file
The problem is you are using single quotes both to denote the argument and you have them inside the string you are trying to match, so the shell just strips them, and the match fails.
Use double quotes around the argument:
sed "s+// Configure::write('debug', 2);+Configure::write('debug', 2);+g" -i file
Note that depending on the version of sed you are using, you may need to escape the parentheses so they are not treated as a capture group.
I tested with GNU sed version 4.7 and it is not needed, the example above works, but it also expects a lower case i as the "in place" parameter.
Related
This question already has answers here:
How to insert strings containing slashes with sed? [duplicate]
(11 answers)
Closed 6 years ago.
I am trying to replace a script call with a script call from a sub directory.
For example, originally I had ./output.sh in my script to call the output.sh script in the current directory.
I want to replace ./output.sh with ../output.sh so that it calls output.sh in the parent directory.
I tried
sed -i -e 's/../\output.sh/./\output.sh/g' scriptName.sh
This returns with
char 17: unknown option to 's'
Any help with the sed escape character syntax would be great.
Sed is bad at this; you'll risk turning an already existing ../output.sh into .../output.sh if you're not careful.
This is the best sed can do:
sed -i 's#output\.sh#../$#g' scriptName.sh
(I'm using # in place of / so that there are no forward slashes to escape. Sed accepts any punctuation character in place of forward slash.)
Note that this will convert ../output.sh to ../../output.sh but at least it doesn't create that triple-dot error.
Instead, try perl:
perl -pie 's#(?<!\.\./)(output\.sh\b)#../$1#g' scriptName.sh
This uses a negative look-behind to ensure it doesn't traverse to the parent's parent. It also allows using \b to denote a word break just in case you have something like output.shelf somewhere.
This would do the trick. Substitutes every appearance of ./output.sh for ../output.sh :
sed 's/\.\/output\.sh/\.\.\/output\.sh/g' scriptName.sh
The escape character is \. You should use it to escape:
Every dot .. The dot is used as any character in regex.
Every slash /. The slash character is used as delimiter between regex on the scommand.
The slash character is special in sed's s command if you formulate it as s/something/replacement/flags, so the slashes in your file paths cause the error. Fortunately, you can use any other character right after s, for example s#something#replacement#flags. So, replacing the command with s#\./output.sh#../output.sh#g should do the trick.
Note two additional changes: you have to escape the dot in first expression since it's also a special character in regex and you also got reversed order of search expression and replacement (thanks charli for noticing this). You don't need the backslashes before o characters, either.
Alternatively, you can use / after s but escape the literal slashes you want to replace by preceding them with backslashes: s/\.\/output.sh/..\/\output.sh/g. It seems in your code you tried to use this solution but put the backslashes after instead of before the slashes.
I want to delete first sign in a file (without creating new file). That is the line (and this line isn't the first one or last one):
#$config['rrdcached'] = "unix:/var/run/rrdcached.sock";
I'm trying to do thuis with sed command but it doesn't work. That is my command:
sed -i "s/#$config\['rrdcached'\].*$/$config\['config'\]/g" text.txt
Any suggestions?
Just replace the first match of # with following command:
sed -i '1 s/#//' test.txt
The $ characters are causing two problems.
First, the shell is treating $config as a variable reference, and replacing it with the value. You need to escape the $ to prevent that.
Second, $ has special meaning in regular expressions, so you need to escape it at that level as well. So you need to escape the backslash and the $.
sed -i "s/^#\\\$config\['rrdcached'\].*\$/\$config['config']/" text.txt
There's no need for the g modifier since you only want to replace the first match on the line. And you should use the ^ anchor so it only matches this at the beginning of the line.
It's also not necessary to escape special regexp characters in the replacement string.
This command works, but i forgot that there is something after '='. At now, everything after that is deleted.
I wrote this:
sed -i "s/^#\\\$config\['rrdcached'\] = "unix:/var/run/rrdcached.sock";.*\$/\\\$config\['config'\]/ = "unix:/var/run/rrdcached.sock";" text.txt
I am trying to replace a line in a file with multiple lines. When I had only one new line char ( \'$'\n ). it worked fine, however when I use two of them, it escapes my sed and the file wont run anymore.
sed 's/TextImLookingFor/My\'$'\nReplacement\'$'\nText/g' /path/to/File.txt
File.txt:
This is a file
TextImLookingFor
look at all this text
DesiredOutput
This is a file
My
Replacement
Text
look at all this text
Actual Output
unexpected EOF while looking for matching ''''
syntax error: unexpected end of file
Using older BSD sed you can do:
sed $'s/TextImLookingFor/My\\\nReplacement\\\nText/' file
This is a file
My
Replacement
Text
look at all this text
This should work with newer gnu-sed as well. However newer gnu-sed may just need:
sed 's/TextImLookingFor/My\nReplacement\nText/' file
This might work for you (GNU sed):
sed '/TextImLookingFor/c\My\nReplacement\nText' file
The problem with this command
sed 's/TextImLookingFor/My\'$'\nReplacement\'$'\nText/g' /path/to/File.txt
is that it isn't parsing the way you expect it is.
You cannot escape a single quote inside a single quoted string. You can escape a single quote inside a $'...' quoted string however (I'm not really sure why).
So the above command does not parse this way (as you might expect):
[sed] [s/TextImLookingFor/My\'$[\nReplacement\'$]\nText/g] [/path/to/File.txt]
instead it parses this way:
[sed] [s/TextImLookingFor/My\]$[\nReplacement\'$]\nText/g' [/path/to/File.txt]
with a mismatched single quote at the end and an unquoted \nText/g bit.
That is the cause of your problem.
If you can't just use \n in your replacement (your version of sed doesn't support that) and you need to use $'\n' then you would need to use something like
sed 's/TextImLookingFor/My\'$'\nReplacement\\'$'\nText/g' /path/to/File.txt
I am trying to set an IP in a file with sed. I am running this command
sed -i 's:$dbserver='':$dbserver='10.0.0.2':' t.conf
but when I look in t.conf the line is
$dbserver=10.0.0.2''
Anyone know why the two single quotes are appearing at the end of the line?
I am running Debian Linux
You need to enclose the second sed argument in double quotes:
sed -i "s:$dbserver='':$dbserver='10.0.0.2':" t.conf
This way $dbserver will be substituted with its value before being passed to sed, and the single quotes won't need escaping.
If you want $dbserver to appear literally in the conf file, preceed the dollar signs with a backslash.
In my project.pro file I have:
DEFINES += VERSION=\\\"1.13.1\\\"
I'd like to replace whatever the current version number is, with a new one in a Bash script:
VERSION_MAJOR=1
VERSION_MINOR=14
VERSION_PATCH=1
sed -i "s/\([0-9]+.[0-9]+.[0-9]+\)/\1${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}/" project.pro
Why is that not working?
So far I have managed to get either no matches at all or then some weird replace-only-the-last-number substitutions.
You may use this sed:
sed -i.bak -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/" project.pro
Few problems in your attempt:
Without extended regex mode (-E), + cannot be used unescaped.
dot needs to be escaped in a regex
No need to use a capture group and back-reference \1.
PS: .bak is extension of backup file so that you can get original file, in case of a wrong substitution.