Это правильно в сопоставлении? - PullRequest
1 голос
/ 28 декабря 2011

Следующий код работает для получения значения состояния 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 ]

1 голос
/ 29 декабря 2011

Исходя из того, что я понял о проблеме, это может сработать -

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
1 голос
/ 28 декабря 2011

Я бы добавил пробел после каждой строки, чтобы избежать проблемы, замеченной @fge. В частности, без него вы бы сопоставили «tcp», если «tcp6» находится в файле.

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]')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...