我想httpd
使用sed
或来注释/取消注释以禁用/启用实例中两个配置节标记之间的缓存awk
。
我可以注释/取消注释以Cache
/Expires
关键字开头的行,但这仍然使模块标记被注释。如何以这样的方式注释/取消注释,即通过单个命令注释/取消注释开始标记和结束标记之间的每一行。
这是一个示例缓存配置。
#<IfModule mod_cache.c>
#
#<IfModule mod_disk_cache.c>
# CacheRoot "/var/cache/mod_proxy"
# CacheEnable disk
# CacheEnable disk
# CacheEnable disk
# CacheIgnoreCacheControl On
# CacheDirLevels 1
#</IfModule>
#
#</IfModule>
#<IfModule mod_expires.c>
# Header set Cache-Control "max-age=604800, public"
# ExpiresActive On
# ExpiresDefault "access plus 1 week"
# ExpiresByType text/cache-manifest "access plus 0 seconds"
# ExpiresByType text/html "access plus 1 year"
# ExpiresByType text/xml "access plus 0 seconds"
# ExpiresByType application/xml "access plus 0 seconds"
# ExpiresByType application/json "access plus 0 seconds"
# ExpiresByType application/rss+xml "access plus 1 hour"
# ExpiresByType application/atom+xml "access plus 1 hour"
# ExpiresByType image/x-icon "access plus 1 week"
# ExpiresByType image/gif "access plus 1 month"
# ExpiresByType image/png "access plus 1 month"
# ExpiresByType image/jpg "access plus 1 month"
# ExpiresByType image/jpeg "access plus 1 month"
# ExpiresByType video/ogg "access plus 1 month"
# ExpiresByType audio/ogg "access plus 1 month"
# ExpiresByType video/mp4 "access plus 1 month"
# ExpiresByType video/webm "access plus 1 month"
# ExpiresByType application/x-font-ttf "access plus 1 month"
# ExpiresByType font/opentype "access plus 1 month"
# ExpiresByType application/x-font-woff "access plus 1 month"
# ExpiresByType image/svg+xml "access plus 1 month"
# ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
# ExpiresByType text/css "access plus 1 year"
# ExpiresByType application/javascript "access plus 1 year"
#</IfModule>
所以我想要一个命令,可以注释标签开始之间的每一行,<IfModule mod_cache.c>
直到它关闭,所以适用于<IfModule mod_expires.c>
.
答案1
尝试这个,
在脚本中添加以下内容来注释或取消注释模块
if [ "$2" == uncomment ]; then
sed -i "/<IfModule $1>/,/<\/IfModule>/ s/^#//" apache.conf
elif [ "$2" == comment ]; then
sed -i "/<IfModule $1>/,/<\/IfModule>/ s/^\(<\| \)/#\1/" apache.conf
fi
运行脚本的语法:
sh script.sh <moduleName> <comment/uncomment>
例子:
sh script.sh mod_disk_cache.c uncomment
答案2
您可以使用 中的简单状态机来完成此操作awk
。为了简单起见,我们假设mod.xml
包含:
#stuff
#
#<IfModule mod_disk_cache.c>
# CacheRoot "/var/cache/mod_proxy"
# CacheEnable disk
# CacheEnable disk
# CacheEnable disk
# CacheIgnoreCacheControl On
# CacheDirLevels 1
#</IfModule>
#
#other stuff
然后,
$ cat mod.xml | awk -F'#' 'BEGIN { state = 0; } { if (/mod_disk_cache/) state = !state; if (state) print $2; else print $0; if (/\/IfModule/) state = !state; }' > umod.xml
$ cat umod.xml
#stuff
#
<IfModule mod_disk_cache.c>
CacheRoot "/var/cache/mod_proxy"
CacheEnable disk
CacheEnable disk
CacheEnable disk
CacheIgnoreCacheControl On
CacheDirLevels 1
</IfModule>
#
#other stuff
该state
变量记录我们何时位于要注释/取消注释的块内部 ( state == 0
) 或外部 ( )。state != 0
笔记:这里重要的一件事是上面的块不包含以 a 结尾的子块,</IfModule>
因为这会过早重置状态。如果你需要支持这种情况,那么国家需要捕获更多。例如,考虑将状态设为一个整数,即-1
在目标块之外时的状态,在0
进入目标块时设置为整数,并在进入子块时递增更高的值。
此命令处理您的原始输入,其中mod_cache.c
块具有嵌套子块:
$ cat mod.xml | awk -F# 'BEGIN { state = -1; } { if (/<IfModule mod_cache\.c>/) state = 0; else if (/<IfModule .*>/) state++; if (state >= 0) print $2; else print $0; if (/<\/IfModule/) state--;}'
回到简单的示例,要重新注释,您可以执行类似的操作,只需设置输出字段分隔符(OFS)并在计算结果为 true#
时在每行之前打印出 a :state
$ cat umod.xml | awk -F'#' 'BEGIN { OFS=""; state = 0; } { if (/mod_disk_cache/) state = !state; if (state) print "#", $0; else print $0; if (/\/IfModule/) state = !state; }'
#stuff
#
#<IfModule mod_disk_cache.c>
# CacheRoot "/var/cache/mod_proxy"
# CacheEnable disk
# CacheEnable disk
# CacheEnable disk
# CacheIgnoreCacheControl On
# CacheDirLevels 1
#</IfModule>
#
#other stuff
答案3
要取消注释,我们可以使用以下命令
awk '/#.*IfModule mod_cache.c/,/#.*IfModule mod_expires.c/{gsub("#","",$0)}1' filename
评论
awk '/^<IfModule mod_cache.c/,/^<IfModule mod_expires.c/{$0="#"$0}1' filename