awk регулярное выражение границы слова - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть две машины Linux.Один - 4.4.12-99, один - 4.4.143.Я просто запустил apt upgrade для них обоих.

У меня есть оператор awk, который содержит регулярное выражение, работающее на 4.4.143, но не работающее на 4.4.12-99.Я искал несколько дней и пробовал несколько разных синтаксисов, чтобы обнаружить, что может быть не так.awk не ошибается и не жалуется, просто не соответствует границе слова.Сценарии одинаковы на каждой машине и работают нормально, за исключением этого выражения awk.На том, который не работает должным образом, я могу заставить его соответствовать всем и обеспечить такой результат.

ip=$(awk -v sUSER="$sUSER" 'BEGIN{gsub(/\./,"\\.",sUSER)}match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) && $0 ~ ("[^[:alnum:]]"sUSER"$") && $0 !~ /^$/ && $0 !~ /^#/{print $1}' /etc/hosts )

awk просматривает файл / etc / hosts с переменной $ sUSER и пытается сопоставитьпользователю на связанный IP-адрес.

Я не могу понять, что я делаю неправильно.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Ответ hek2mgl - это то, что вы должны использовать.

Для вашего вопроса по awk задокументированы регулярные выражения awk GNU: https://www.gnu.org/software/gnulib/manual/html_node/gnu_002dawk-regular-expression-syntax.html

Они используют \< и \> в качестве нулямаркеры границы ширины слова, так что вы можете сделать

gawk -v sUSER="$sUSER" '
    BEGIN {
        gsub(/\./,"\\.",sUSER)
        ipv4Re = "^[0-9]+(\\.[0-9]+){3}$"
        sUserRe = "\\<" sUSER "\\>"
    }
    /^$/ || /^#/ {next}
    $1 ~ ipv4Re && $0 ~ sUserRe {print $1}
' /etc/hosts 

(пробел это хорошо, вы должны попробовать его использовать)


другой подход заключается в циклическом обходе полей и использовании равенства строккоторый автоматически охватывает границы слов.Это будет работать с gawk или mawk

awk -v sUSER="$sUSER" '
    !/^#/ {for (i=2; i<=NF; i++) if ($i == sUSER) print $1}
' /etc/hosts
0 голосов
/ 21 ноября 2018

Что вы в основном хотите сделать, так это поиск локального имени хоста.Для этой цели существует инструмент под названием getent:

getent -s files hosts "${sUSER}" | cut -d' ' -f1

-s files указывает getent использовать только локальные базы данных хоста (не DNS), что составляет /etc/hosts.

...