Linux 使用sed将缺少的ServerName添加到httpd.conf文件

Linux 使用sed将缺少的ServerName添加到httpd.conf文件,linux,sed,Linux,Sed,我在httpd.conf文件中有以下虚拟主机 <VirtualHost *:80> ## could be comments could be any line could be any line could be any line </VirtualHost> <VirtualHost *:80> could be any line ## could be comments

我在httpd.conf文件中有以下虚拟主机

    <VirtualHost *:80>
    ## could be comments
    could be any line
    could be any line
    could be any line
    </VirtualHost>

    <VirtualHost *:80>
       could be any line
    ## could be comments
    could be any line
    could be any line
    could be any line
    could be any line
    could be any line
    </VirtualHost>

    <VirtualHost *:80>
## may have comments
    ServerName ppp.com
        could be any line
    could be any line
    could be any line
  </VirtualHost>

    <VirtualHost *:443>
   ## could be empty
    ServerName zzz.com
    could be any line
    could be any line
    could be any line
    </VirtualHost>

##可能是评论
可以是任何一行
可以是任何一行
可以是任何一行
可以是任何一行
##可能是评论
可以是任何一行
可以是任何一行
可以是任何一行
可以是任何一行
可以是任何一行
##可能有意见
服务器名ppp.com
可以是任何一行
可以是任何一行
可以是任何一行
##可能是空的
ServerName zzz.com
可以是任何一行
可以是任何一行
可以是任何一行
我正在尝试将“ServerName abc.com”添加到每个尚未设置ServerName的虚拟主机

我试着在sed中这样做,但我一事无成。。有什么帮助吗

这就是我目前所拥有的

sed '/^[ \t]*<VirtualHost/,/^[ \t]*<\/VirtualHost/{
/^ServerName/!{
   /<VirtualHost/{
     /^/a\ServerName abc.com

   }
  }
}' httpd.conf

sed'/^[\t]*我认为awk可能更适合这个任务。下面是添加服务器名称。awk

/<VirtualHost/ { named=0; indent=substr($0,1,match($0,/<VirtualHost/)-1) }
/^[[:blank:]]*ServerName[[:blank:]]*/ { named=1; }
/<\/VirtualHost>/ { if (!named) print indent "ServerName abc.com" }
{ print }

Awk在这方面会有更好的帮助。它可以更好地处理多行,而且httpd.conf已经是一种记录格式

# adServer.awk
BEGIN { RS = "</VirtualHost>" }  #separate records on end of a Virtual Host
$0 /ServerName/ { print $0 $RS}  # used for records with a name

$0 ~ /ServerName/ {   # else
    for  ( i = 1; i <= NF; i ++ ) {
        print $i
        if ( $i /<VirtualHost.*>/ ) {
            print "ServerName abc.com\n"
        }
    }
    print $RS
}
#adServer.awk
开始{RS=”“}#在虚拟主机的末尾分别记录
$0/ServerName/{print$0$RS}#用于具有名称的记录
$0~/ServerName/{#else
对于(i=1;i使用sed:

sed '/<VirtualHost/{
       :a N;/<\/VirtualHost>/!b a;
       /ServerName/!s!\(</VirtualHost>\)!ServerName abc.com\n\1!
}' input

sed'/工作得很好,只是对regex做了一些修改以获得前导空格。是的,服务器名可以是列表中的最后一行VH@user2045331:根据您对需求的澄清,它被简化并处理缩进。这是一个简洁的想法,但不能保证在每个系统上都能工作RS的e字符串值应为输入记录分隔符;默认为a。如果RS包含多个字符,则结果未指定。-POSIX.1-2008足够公平。由于我使用gawk作为实现,正则表达式在RS变量中的工作与预期一致。
sed'/
sed '/<VirtualHost/{
       :a N;/<\/VirtualHost>/!b a;
       /ServerName/!s!\(</VirtualHost>\)!ServerName abc.com\n\1!
}' input