Replace first sign in line (linux bash) - linux

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

Related

Uncomment line using sed

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.

Sed command with exact variable change

I want to replace exact word by sed command with variable. My file looks like this:
//module xyz
module xyz
Suppose I have the following shell variables defined:
var1='module xyz'
var2='module abc'
I want to change xyz to abc in uncommented line only(module xyz)
So after executing command output should be
//module xyz
module abc
I do not want to change commented line (//module xyz)
currently I am using sed command as,
sed -i "s|$var1|$var2|g" file_name
But this command doesn't work. It also replace commented line. How can I only replace the line that isn't commented?
Assuming that you know the pattern is at the start of the line, you can use this:
sed "s|^$var1|$var2|" file_name
That is, add an anchor ^, so that the match has to be at the start of the line.
I removed the -i switch so you can test it and also the g modifier, which isn't necessary as you only want to do one substitution per line.
It's worth mentioning that using shell variables in sed is actually quite tricky to do in a reliable way, so you should take this into account.
Your shell variable assignment should be quoted if there is space. Like:
var1="foo bar blah"
You can add pattern, "the lines don't start with // " to your sed command, so that do your substitution only for those lines
This line should work for your example:
sed -i "\#^//#\!s/$var1/$var2/g" file
the ! needs to be escaped, because we used double quote
since your pattern (comment) has slash (/), I used other char as regex separator
This command will only do substitution on lines not starting with //. If there are leading spaces, you may want to adjust the pattern ^//
You need to identify a pattern so that lines containing that pattern should not be processed.
Assuming that // will exist only in commented lines you can use
sed -i '/\/\// !s/$var1/$var2/g' file_name
/\/\// will enable sed to identify lines which contain the pattern //, and !s will enable you to skip those lines.

delete and replace a line using linux command

I am trying to delete a line with the pattern matches and replacing the entire line with the another line using sed command.
File contents:Sample.txt
Testfile=xxxx
Testfile3=uuuu
Testfile4=oooo
Testfile5=iiii
Testfile2=ikeii
I am using sed command to delete a line contains Testfile3=* and replace by Testfile3=linechanged
sed -i 's/Testfile3=\*/Testfile3=linechanged/' Sample.txt.
But it just appends the replaceable string in the line as shown below
Testfile3=linechanged=uuuu.
I am expecting the output to be
Testfile3=linechanged.
What i am doing wrong?
The star is not matched right:
sed -i 's/Testfile3=.*/Testfile3=linechanged/' Sample.txt
# ^^
.* matches any character (.) for any length (*), so it will match everything till the end of the line.
You can use captured group to keep what will be preserved and use the desired replacement for the rest:
sed -i 's/^\(Testfile3=\).*/\1linechanged/' file.txt
In your case, escaping the Regex token * like \* will match * literally e.g. Testfile3=* would be matched then.
This might work for you (GNU sed):
sed '/Testfile3/cTestfile3=linechanged' file
This matches the line containing Testfile3 and changes it to the required string.

Replacing string having forward slash in sed

I wish to replace
x.y.z.zz=/a/b/c/d/
with
x.y.z.zz=/a/b/e/d/
i know x.y.z.zz in advance.I also know the line number in advance.
I have tried this
sed "11s/.*/x.y.z.zz=\/a\/b\/e\/d\/" filename
but this is giving error. Is there a better way to directly search and replace the string ?
sed replaces by using the sed 's/pattern/replacement/' syntax. In your case, you were missing the last /. So by saying this it will work:
sed '11s/.*/x.y.z.zz=\/a\/b\/e\/d\//' file
^
However, it may be cleaner to use another delimiter, so that the syntax is more clear. What about #? (It can also be ~, _, etc.):
sed '11s#.*#x.y.z.zz=/a/b/e/d/#' file
Test
$ cat a
a
x.y.z.zz=/a/b/c/d/
b
c
Let's replace line 2:
$ sed '2s#.*#x.y.z.zz=/a/b/e/d/#' a
a
x.y.z.zz=/a/b/e/d/
b
c
You can just replace c with e if you know your input will always have "x.y.z.zz=/a/b/c/d". e.g. just executing sed s/c/e/
will just replace c with e in the line. Also, you don't need to change the complete line always. You can just change a character or a word in the text.Additionally, if a line contains more than one occurrence of character/word, this command will only change the first one e.g. if input string is x.y.z.zz=/a/b/c/d/c, executing sed s/c/e/ will have output x.y.z.zz=/a/b/e/d/c
If all the occurrences need to be changed g (global) needs to be added in sed command e.g. sed s/c/e/g will give output x.y.z.zz=/a/b/e/d/eIf sed needs to be executed only for a particular line, line number shall be mentioned in the sed command itself, as done in the question. This is the link (http://www.grymoire.com/Unix/Sed.html), I always refer when in question with sed

I am having trouble with Sed

I am trying to use the sed command to replace this line:
charmm.c36a4.20140107.newcali4.fixhcali.grange.b
with:
charmm.20140911.c36a4.3rd.ghost2.model3rd
When I use:
sed -i '/s/firstline/secondline/g'
It doesn't work. I think the periods are messing it up. How do I get around this?
sed uses regular expressions, so . matches any character. If you want to only match the . character itself, tell sed to look for \.
so to change the first line into the second line:
sed -e 's/charmm\.c36a4.20140107\.newcali4\.fixhcali\.grange\.b/charmm.20140911.c36a4.3rd.ghost2.model3rd/g' < filetochange >newfile
Here, I added "g" so it does it globally, ie, if there are several instances on the same line, all will be changed. If you remove the "g", it will only change the first occurence on each line.
It reads from filetochange and writes to newfile
If you do :
sed -i -e 's/charmm\.c36a4.20140107\.newcali4\.fixhcali\.grange\.b/charmm.20140911.c36a4.3rd.ghost2.model3rd/g' filetochange
it will directly do the change in "filetochange" ... but please be careful, a badly written sed -i could mess up the file and make it unusable
The s command follows this syntax:
s/pattern/replacement/
You need to drop the / in front of the sed command.

Resources