Regex 这个匹配正确吗?

Regex 这个匹配正确吗?,regex,linux,shell,awk,pattern-matching,Regex,Linux,Shell,Awk,Pattern Matching,以下代码用于从以下给定的文件中获取a的状态值(如果启用)、d的状态值(如果禁用)和n的状态值(如果不存在): # Check whether the service entry exists and whether it is enabled or disabled # Status value 'a' states that the service is uncommented in /etc/inetd.conf. # Value 'd' states that the service is

以下代码用于从以下给定的文件中获取
a
的状态值(如果启用)、
d
的状态值(如果禁用)和
n
的状态值(如果不存在):

# Check whether the service entry exists and whether it is enabled or disabled
# Status value 'a' states that the service is uncommented in /etc/inetd.conf.
# Value 'd' states that the service is commented, and value 'n' specifies
# that the service entry doesnt exist in the configuration file.
status=`awk -v serv=$1 -v proto=$2 -v exist="n" '
        BEGIN {
        format=sprintf("^[\t ]*%s.*%s",serv,proto);
        comformat=sprintf("^[\t ]*#[\t ]*%s.*%s",serv,proto);
        }
        {
        if(match($0,format))
        {
                exist="a";
        }
        else if(match($0,comformat))
        {
                exist="d";
        }
        }
        END {
        printf("%s",exist)
        }' $INETD`
从以下文件:

ftp     stream  tcp6    nowait  root    /usr/sbin/ftpd         ftpd
telnet  stream  tcp6    nowait  root    /usr/sbin/telnetd      telnetd -a
shell   stream  tcp6    nowait  root    /usr/sbin/rshd         rshd
#kshell  stream  tcp     nowait  root    /usr/sbin/krshd        krshd
login   stream  tcp6    nowait  root    /usr/sbin/rlogind      rlogind
#klogin  stream  tcp     nowait  root    /usr/sbin/krlogind     krlogind
注意:
$1
=文件中的第1列,
$2
=文件中的第3列

所以我关心的是,如果使用以下格式进行上述搜索是否足够好?或者是否有其他更好的正则表达式:

 format=sprintf("^[\t ]*%s.*%s",serv,proto);
 comformat=sprintf("^[\t ]*#[\t ]*%s.*%s",serv,proto);

我会在每个字符串后面添加一个空格,以避免@fge看到的问题。特别是,如果没有它,如果文件中有“tcp6”,您将匹配“tcp”

format=sprintf("^[\t ]*%s[\t ].*%s[\t ]",serv,proto);
comformat=sprintf("^[\t ]*#[\t ]*%s[\t ].*%s[\t ]",serv,proto);
使用一个大的BEGIN块并不是非常惯用的AWK,但它可能是一个解决方案,它的模式来自外部


如果您的AWK实现支持POSIX regexp,您还可以使用“[:space:]”类来匹配更多的空白(“[\t\r\n\v\f]”)

根据我对问题的理解,这可能会起作用-

status=$(awk -v serv="$1" -v proto="$2" '
$1==serv && $3==proto {val="a";exit}
$1=="#"serv && $3==proto {val="d";exit}
END{if ((val=="a") || (val=="d")) print val; else print "n"}' $INETD)
测试:基于手动传递值并在文件中使用以下内容

[jaypal:~/Temp] cat f1
ftp     stream  tcp6    nowait  root    /usr/sbin/ftpd         ftpd
telnet  stream  tcp6    nowait  root    /usr/sbin/telnetd      telnetd -a
shell   stream  tcp6    nowait  root    /usr/sbin/rshd         rshd
#kshell  stream  tcp     nowait  root    /usr/sbin/krshd        krshd
login   stream  tcp6    nowait  root    /usr/sbin/rlogind      rlogind
#klogin  stream  tcp     nowait  root    /usr/sbin/krlogind     krlogind

[jaypal:~/Temp] awk -v serv="kshell" -v proto="tcp" ' # kshell exists but is commented
$1==serv && $3==proto {val="a";exit}
$1=="#"serv && $3==proto {val="d";exit}
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1
d
[jaypal:~/Temp] awk -v serv="ftp" -v proto="tcp6" ' # tcp6 proto exits
$1==serv && $3==proto {val="a";exit}
$1=="#"serv && $3==proto {val="d";exit}
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1
a
[jaypal:~/Temp] awk -v serv="ftp" -v proto="tcp" ' # tcp proto does not exist
$1==serv && $3==proto {val="a";exit}
$1=="#"serv && $3==proto {val="d";exit}
END{if ((val=="a") || (val=="d")) print val; else print "n"}' f1
n

如果您有两个名为“service”和“service2”的服务,您将遇到问题:您的正则表达式将同时匹配这两个服务。有什么替代方案?而是正确的方法吗?我不知道awk,但你已经有了它,可以为你分割领域了。如果我是你,我会检查第一个字段是否与“$service”或“#$service”相等。
$2(即column3)
有什么用?@JaypalSingh它告诉我们使用哪个协议。IPv4/6