这样的匹配正确吗?

发布于 2024-12-23 04:36:10 字数 1558 浏览 4 评论 0原文

以下代码用于获取 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);

The following code works to get the status value of a if its enabled, d if its disabled and n if its not present from a file given below:

# 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`

From the following file:

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

Note: $1 = column 1 in the file and $2 = column 3 in file.

So my concern is if the above searching using the following format good enough? or is there anyother better regular expression:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深者入戏 2024-12-30 04:36:10

根据我对问题的理解,这可能有效 -

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

Based on what I have understood of the problem this might work -

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)

Test: Based on passing the values manually and using the below content in file

[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
新一帅帅 2024-12-30 04:36:10

我会在每个字符串后面添加一个空格以避免@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\v\f]')

I would add a space after each string to avoid the problem seen by @fge. In particular, without it, you would match "tcp" if "tcp6" is in the file.

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

Using a big BEGIN block is not very idiomatic AWK but it's maybe the solution with a pattern coming from outside like that.

If your AWK implementation supports POSIX regexp, you can also use the '[:space:]' class to match more kink of whitespaces (='[ \t\r\n\v\f]')

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文