shell 中两个标签之间的注释行

shell 中两个标签之间的注释行

我想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

相关内容