I have a configuration file and I want to replace a line containing a specific string, lets say test :
file.conf
aaa
bbb
ccc
// test
ddd
// test
My line of code is not working, I'm new to sed.
sed -i `s#^//[ \t]test#test#g'
Some guidance ?
I have a configuration file and I want to replace a line containing a specific string, lets say test :
file.conf
aaa
bbb
ccc
// test
ddd
// test
My line of code is not working, I'm new to sed.
sed -i `s#^//[ \t]test#test#g'
Some guidance ?
First of all, I'd recommend to avoid the use of -i
as it will replace the files in-place without confirmation.
This is a working version of what you were trying to accomplish and outputs to the standard output (the terminal):
sed 's#^//[ \t]test$#test#g' file.conf
aaa
bbb
ccc
test
ddd
test
Optionally pipe it through less by appending | less
to be able to paginate through large amounts of output.
The above is all very specific to the sequence of test
, so to more generalize, you can try this:
sed 's#^//\s\(.*\)$#\1#g' file.conf
It will remove the //
part and any whitespace until the actual text, whatever this text is.
If you like the result, you can add the -i
flag again to replace the file.
To tell more about your attempt and explain why my example does work:
sed -i `s#^//[ \t]test#test#g'
'
) should have been used here probably.#
) are your chosen delimiter, a good alternative to the common forward slash (/
) as your match is about this same character and this avoids the need for escaping.The pattern in the command s/regexp/replacement/
is a standard one as mentioned in the manpage, among many others: man 1 sed
:
s/regexp/replacement/
Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character
&
to refer to that portion of the pattern space which matched, and the special escapes\1
through\9
to refer to the corresponding matching sub-expressions in the regexp.
rexexp
in the above is a commonly used abbreviation for regular expressions.^//[ \t]test$
matches lines starting (^
) with two forward slashes, followed by a space or a tab character, followed by the exact sequence test
and a line ending ($
).g
flag is to do this operation in a global way as explained here.You do not have to use forward slashes as separator. In fact, I recommend using other separators like comma or hashes for readability.
-i
is also your friend, but only use it if you know for sure it is correct. In this case, I would do something like:
sed -r 's,^//[ \t]*(.+),\1,' file.conf | less
I use -r
here for extended regexp, so I do not have to escape the parentheses. Furthermore, it allows me to use the plus operator which means "one or more occurrences". The following expression would be equivalent:
sed 's,^//[ \t]*\(..*\),\1,' file.conf | less
(one dot to match at least one character followed by zero or more of any character)
After I am sure that the replacement is correct (type slash followed by your keywords in less
for searching), I close less by typing q
and navigate to the previous history entry by pressing the Up key. I then delete | less
and type -i
to proceed with the replacement:
sed -r 's,^//[ \t]*(.+),\1,' file.conf -i
If you want to gain a deeper understanding of sed, I can recommend you reading the info page of sed which is more extended than the manual page:
info sed