ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

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.

Introduction to Linux - A Hands on Guide

This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.

:t
/<VirtualHost/,/VirtualHost>/ { # For each line in this range
/VirtualHost>/!{ # If not at the /VirtualHost>/ marker
$!{ # nor the last line of the file,
N; # add the Next line to the pattern space
bt
} # and branch (loop back) to the :t label.
} # This line matches the /VirtualHost>/ marker.
/lal.com/d; # If /lal.com/ matches, delete the block.
} # Otherwise, the block will be printed.

Rather than having all Apache virtual hosts configured in a single file, I recommend using instead

Code:

Include *.vhost

and creating a separate file for each virtual host (in the base Apache configuration file directory, named domainname.vhost). That way you could just delete the file.

However, your current problem can be easily solved via awk. It is not very elegant, but it should work well for you. It is not terribly well tested, but it worked flawlessly with the few VirtualHost configurations I tried it with. It modifies the specified configuration file, but saves the previous version with the suffix .saved.

The shell script prints the usage information if necessary, creates (and autodeletes) a safe temporary working directory, saves and replaces the original file if success, or prints an error message if necessary. The real work is done in the awk script.

The awk script is a case insensitive line-based state machine. In the default state, it just outputs each input line as is.

When the awk script encounters a line with the first token matching <VirtualHost, it changes state, and starts saving each input line into (a new) array vhost instead of outputting them.

If the awk script encounters an input line with the first token matching ServerName, it checks if any of the specified server names are contained in the second token. If yes, this array is marked to be skipped.

When the script encounters a line with the first token matching </VirtualHost>, it will reset to default mode. If the array was not marked skipped, all lines in the array are output at this point.

There are a few minor tricks in there to make sure the script works with both gawk (GNU awk, my favourite) and mawk, but they're not very important unless you're very interested in awk scripting.

you are right. I just had a look at your solution and noticed that you omit the '</' part. This spares us the obfuscating escape character.
Examining your solution a bit further, you can transform it to

Code:

sed ':t /VirtualHost>/! {N;bt}; /lal.com/ d' infile

which has "negative" check conditions to loop the file. It is also shorter than mine by one instruction.

Also I'm guessing that the ":a N;" and "; ba" set up a loop in
which the "{...}" command is run. Does it simply match from the
first occurrence of "\@</VirtualHost>@" to the next occurrence?

Or does it effectively create sections, and if "/lal.com/" is
matched it deleted the section?

It does the latter. I reads every line into the pattern buffer. If '\@</VirtualHost>@' is encountered it checks for /lal.com/ and deletes the pattern buffer if it finds lal.com. Regardless of the presence of lal.com it then jumps to the end of the sed script which also triggers sed's default action to print the pattern buffer. The buffer will be empty if lal.com were previously encountered; otherwise the content is printed and the script starts again with processing the next block.