Reputation: 2868
I want to delete a block of specific server from this file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
<VirtualHost *>
DocumentRoot "documentroot"
ServerName newserver
</VirtualHost>
So far I've used the following, but it doesn't seem to give me the proper result, but instead greps for each line of the block (of the inner grep) individually.
grep -vF "$(grep -w -B 2 -A 1 'newserver'/Applications/MAMP/conf/apache/httpd.conf)" /Applications/MAMP/conf/apache/httpd.conf;
The above results in the following:
NameVirtualHost *
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
While instead I want the following:
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
Upvotes: 0
Views: 3416
Reputation: 4265
Another one with diff
and parts of your initial command:
diff <(grep -w -B 2 -A 1 'newserver' /Applications/MAMP/conf/apache/httpd.conf) \
/Applications/MAMP/conf/apache/httpd.conf |
grep -e '^> ' | sed -e 's/^> //'
Upvotes: 2
Reputation: 2761
awk alone:
$ awk '!/ServerName newserver/{printf "%s%s", $0, RS}' RS='</VirtualHost>' file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
RS
defines </VirtualHost>
as record separator and awk
will prints those records($0
) that doesn't match with ServerName newserver
in it. And then print the RS
(</VirtualHost>
) again which is removed when we change RS to that.
Upvotes: 2
Reputation: 785621
If you want to delete an entry with ServerName newserver then use this perl one-liner:
perl -0pe 's~(?s)\s?<VirtualHost[^>]*>((?!</VirtualHost>).)*ServerName newserver.*</VirtualHost>~~' file
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
Using a variable:
s='newserver'
perl -0pe 's~(?s)\s?<VirtualHost[^>]*>((?!</VirtualHost>).)*ServerName '"$s"'.*</VirtualHost>~~' file
This perl command uses a regex that matches a block starting from these 2 tags:
<VirtualHost[^>]*>
and
</VirtualHost>
and finds this pattern in between these 2 patterns:
ServerName newserver
It uses a negative lookahead pattern using (?!</VirtualHost>)
that makes sure only when ServerName
test comes then only match is found.
Upvotes: 1
Reputation: 185550
$ tac vhost | awk 'NR>4' | tac
NameVirtualHost *
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost
</VirtualHost>
<VirtualHost *>
DocumentRoot "/Applications/MAMP/htdocs/bedrock/web"
ServerName bedrock
</VirtualHost>
This is a 'trick' to remove the last Vhost by the known numbers of lines it contains
Upvotes: 1