Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Now I need to implement a function to a script to switch between the different options. Ie. comment out the next line after the pattern "option1" and remove the comment from the next line after "option2" to activate it. Ideally I'd need a command that would first make sure that each next line after "option[1-3]" is commented out and then remove the comment from the line after "option2".
I'm not that bad at bash, but sed and awk are giving me some headache at the moment, I hope someone can help me with this.
What exactly do you mean? Of course this is just an example file, the ones I want to use this for have a _lot_ more and various content and there are plenty of them (vHosts).
I mean you have a template file with the full content and some keywords like THIS_IS_THE_PLACE_FOR_OPTION_1 ....
and that can be easily replaced in a single sed: s/OPT_KEYWORD_1/opt_value_1/ ...
So you do not need to take care of the generated files at all.
Yeah well this would be possible if the content of the file would stay the same. But imagine 50+ vHost configs with different IPs and domain names, it would be a mess in this case. Also the option strings are very long and not just a few words like in my example case, so I can't just replace the whole string.
sed -r -e '/^# option2/ { n ; s/^#// }' -e '/^# option/ { n ; s/^#*(.)/#\1/ }' file
The first -e expression says that, if the current line matches option2, then move on to the next line and substitute away any #'s at the start of it. The second -e is then applied and works the same way, only this time ensuring that there is a # at the front of every line.
Notice that the order of the two expressions is important in this case. The second expression ignores the "option2" line only due to the n option in the first expression. it means that that line is passed up and gone before the second expression ever has a chance to see it.
Many thanks David, it seems to be exactly what I was looking for (sed with n) and your explaination is very nice.
PS: Would you mind explaining the regex of the second part "s/^#*(.)/#\1/" a little more, so I completely understand it, or do you know any good paper on sed's regex? For example I don't understand this regex "*(.)" and this one "\1". Thank you in advance!
^ means beginning of line
#* means any number of # (including 0 or more)
(.) dot means any character, (.) means it is grouped
/ is a delimiter, between the first two there is a search expression, after the second one there is a replace expression:
# means # itself
\1 means the first group found in the search expression - which was (.)
man sed is a good place to start with (see links also at the end)
_____________________________________
If someone helps you, or you approve of what's posted, click the "Add to Reputation" button, on the left of the post.
Happy with solution ... mark as SOLVED
(located in the "thread tools")
^ == The start of the line #* == A hashmark, found zero or more "*" times (.) == Any single character ".", captured in parentheses for use in the replacement
In essence, it matches all lines with and without #'s in front of them. The important thing is to capture the first non-# character.
You could replace the "*" with a question mark"?", for zero or one times, assuming that there's always only a single #.
The right-hand side:
Code:
#\1
# == A single hashmark \1 == The contents of the first set of parentheses in the LHS match
So it takes whatever character is captured above and adds a hashmark to it, and this replaces the entire match. If the line had a hash previously, it ends up unchanged.
Notice the use of the -r option too. backreferencing, as this is generally called, is an extended regex feature in sed.
Regular expressions come in several flavors, as supported by different tools, but it's generally in the more advanced features where they differ. The big thing to worry about in grep and sed is the difference between basic and extended regex. The grep man page has a good explanation of them.
Last edited by David the H.; 05-31-2012 at 07:25 AM.
Reason: formatting change and a small addition
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.