Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

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 ?

share|improve this question
    
its an interesting question - any reason why you wish to delete this? –  fossfreedom Jan 30 '13 at 12:40
    
I'm working on a script that automatically configures and installs lamp so I need to uncomment two lines in phpmyadmin conf file to accept nopasswd login via the web interface. –  pyn Jan 30 '13 at 12:48
    
@pyn Consider using tools designed specifically for deploying applications instead: Puppet, Juju, Chef, etc. Writing your own scripts to deploy applications is usually reinventing wheels and/or axles. –  gertvdijk Jan 30 '13 at 12:49
    
I'm doing this for learning purposes, to get familiar with bash scripting ( CLI ). –  pyn Jan 30 '13 at 12:53

2 Answers 2

up vote 3 down vote accepted

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'
  • You are using a backtick (`) which is interpreted by your shell rather than Sed. A simple single quote (') should have been used here probably.
  • The hashes (#) 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.
  • The regular expression ^//[ \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 ($).
  • The g flag is to do this operation in a global way as explained here.
  • An input file is missing and should be given after the Sed-command.
share|improve this answer
    
1. backtick, I miss typed 2. I was thinking to use a different delimiter fo clarity purposes 3. Yes, I know. –  pyn Jan 30 '13 at 12:41

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
share|improve this answer
    
I didn't know about the use of alternative delimiters. Thanks - I was wrong in my answer apparently - fixed that now. :) –  gertvdijk Jan 30 '13 at 13:53
    
This^ is what I said above.:) –  pyn Jan 30 '13 at 14:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.