awk соответствует неверному имени хоста в / etc / hosts - PullRequest
0 голосов
/ 17 ноября 2018

Я использую этот код awk, чтобы выбрать IP-адрес в файле / etc / hosts, и хотя я могу заставить его соответствовать правильному имени хоста, awk выберет «почти подобное» имя хоста, если увидит его первым. Я исследовал это, и я не могу понять это.

sUSER=machine_005
ip=$(awk '/^[[:space:]]*($|#)/{next}/'$sUSER'/{print $1; exit}' /etc/hosts)

Я знаю, что первая часть ищет $ или # и, если найден, вызывает следующую строку. Эта функция необходима в окончательной формуле. Другая необходимая функция - остановка после первого матча. Я знаю, что следующий / xxx / ищет шаблон и, если он найден, печатает от $ 1 до $ ip.

Вот пример файла моего хоста

555.555.555.555 machine.005
222.222.222.222 machine_005

если я $sUSER=machine_005 $ip - это 222.222.222.222 точно так же, как вы ожидаете.

если я $sUSER=machine.005 $ip это 555.555.555.555 точно так же, как вы ожидаете

Но если мой / etc / hosts:

222.222.222.222 machine_005
555.555.555.555 machine.005

Тогда, если я $sUSER=machine_005 $ip будет 222.222.222.222, как вы и ожидаете.

Однако, если I $sUSER=machine.005 $ip равен 222.222.222.222 Требуется machine_005 IP-адрес.

Может ли это быть ошибкой? или это специально?

Спасибо.

Hello. Я хотел опубликовать свою последнюю строку кода, которая обеспечивает правильный вывод. Я ценю всю помощь и руководство от тех, кто ответил. Я хотел опубликовать окончательный код на случай, если кто-то в будущем может найти его полезным.

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

Ответы [ 3 ]

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

РЕДАКТИРОВАТЬ 2: согласно ОП необходимо удалить строки, начинающиеся с # и пустые строки, которые я считаю, затем попробуйте выполнить следующее.

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


РЕДАКТИРОВАТЬ: Или для выхода из DOT внутри awk сам код, попробуйте следующее.

sUser="machine.005"
awk -v sUser="$sUser" 'BEGIN{sub(/\./,"\\.",sUser)} match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) && $0 ~ sUser{print $2}'  Input_file


Поскольку DOT рассматривается как любой символ, поэтому он перехватывает все между machine и 005|6, поэтому нам нужно экранировать его, чтобы сообщить программе, что это фактическая точка и ее не следует рассматривать как особую. имея в виду.

Не могли бы вы попробовать следующее.

sUser="machine\\\.005"
awk -v u="$sUser" 'match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) && $0 ~ u{print $2}' Input_file

Вывод будет следующим.

machine.005
0 голосов
/ 18 ноября 2018

getent - это инструмент, предназначенный для извлечения записей из /etc/hosts (и других баз данных конфигурации):

getent hosts "${USER}" | cut -d' ' -f1
0 голосов
/ 17 ноября 2018

В регулярном выражении . соответствует любому символу.Вам нужно экранировать его, чтобы оно совпадало буквально.

sUser='machine\.005'

Если вы получаете значение из пользовательского ввода, вы можете использовать оператор подстановки оболочки:

sUser=${sUser//./\\.}

Также см. Как использовать переменные оболочки в скрипте awk? для лучшего способа включения переменной оболочки в скрипт awk.

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