Peter
Peter

Reputation: 3184

Sed replace in large text

Scenario: Trying to modify large portions of our httpd configuration file using sed.

What I've tried:

read -d '' _OLD <<"EOF"
<Directory "/var/www/html">

#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
    Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    AllowOverride None
EOF

read -d '' _NEW <<"EOF"
<Directory "/var/www/html">

#
# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
#
    Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    AllowOverride All
EOF

echo -n ${_OLD}
echo -n ${_NEW}
sed -i "s/$_OLD/$_NEW/g" /etc/httpd/conf/httpd.conf

If you notice the only thing that changed is AllowOverride All I only want to modify the rule for /var/www/html and not for the other instances hence why I'm looking in that whole block.

I know there is probably a better way to do what I'm trying to accomplish. Direction would be much appreciated.

Upvotes: 0

Views: 936

Answers (3)

Stephen Niedzielski
Stephen Niedzielski

Reputation: 2637

sed -r '\%<Directory "/var/www/html">%,\%</Directory>% s%(AllowOverride)\s+None%\1 All%i'

Upvotes: 2

Well, my (out-of-date) version of sed doesn’t allow multi-line ‘old’ patterns (regular expressions), and requires multi-line replacements to have backslashes before the newlines, as in

sed "s/lifetime/birth\
…\
death/"

…so that’s one or two problems.  Another is that you’re using / as your delimiter even though your pattern and replacement have slashes in them.

I suggest that you use regular expression addresses:

sed '/<Directory "\/var\/www\/html">/,/AllowOverride/s/AllowOverride None/AllowOverride All/'

In other words, do the s/AllowOverride None/AllowOverride All/ substitution on any applicable line(s) between a <Directory "/var/www/html"> line and the next AllowOverride line.  (Watch out for the quotes in the first regular expression.)

Upvotes: 1

rs_atl
rs_atl

Reputation: 8985

Why not use a regex? Sed supports them natively. More details here.

Upvotes: 0

Related Questions