匹配时这是正确的吗?

时间:2011-12-28 12:06:28

标签: 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 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);

2 个答案:

答案 0 :(得分:1)

我会在每个字符串后面添加一个空格,以避免@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正则表达式,您还可以使用'[:space:]'类来匹配更多的空白扭曲(='[\ t \ r \ n \ n \ v \ f]')

答案 1 :(得分:1)

基于我对此问题的理解,这可能有用 -

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