Вопрос: Скрипт сначала ссылается на другой файл


Привет, у меня есть сценарий, и в нем мне нужно получить имена хостов от IP-адресов, которые генерирует сценарий. Сценарий будет генерировать эти IP-адреса в 1 аккуратный файл всего с 1 столбцом. Это буквально только IP-адрес (по 1 для каждой строки). У меня есть еще один файл под названием «db», который выглядит так:

IP Hostname

«db» - это моя база данных, в которой хранится список IP-адресов и имен хостов, делегированных этим IP-адресам. Это статический адрес и не будет меняться, как правило, серверы или коммутаторы и т. Д. Что мне нужно для IP-адресов, которые генерирует сценарий, я бы хотел их разрешить с именами машин FIRST из этого файла базы данных, и если это не так, найдите там, затем запустите host команда. Я уже делаю последнее с host но я действительно хочу, чтобы они пришли из моего db-файла в первую очередь. Конечным результатом должен быть только 1 файл с 1 столбцом имен хостов. У меня есть какие-то идеи, использующие awk с массивами, но, похоже, не совсем то, что мне нужно.


2
2017-09-18 23:27


Источник


Возможно, вы сможете получить более конкретные ответы, если вы разместите часть уже написанного вами сценария. Ответ, который вы ищете, кажется, не просто команды для извлечения информации, но как ее использовать. - prateek61


Ответы:


grep это команда, основной целью которой является просмотр текста для шаблона (или шаблонов). Его упрощенное применение к этой задаче было бы

grep 1.2.3.4 db

который выведет "IP_address Имя хоста"Линия (линий) из db файл которые соответствуют шаблону "1.2.3.4». Заметьте, что я сказал линия(Ы) (скорее, чем линия) а также соответствовать шаблону (скорее, чем содержать строку), потому что здесь есть пара ошибок.

  • Во-первых, grep, как я уже сказал, (по умолчанию) ищет узоры скорее, чем строки, Эти шаблоны называются обычные выражения, и есть мир документации на них. Самый важный факт о регулярных выражениях для этого обсуждения заключается в том, что период ".», это шаблон, который соответствует любому одиночному символу. Так, например, шаблон (регулярное выражение) 1.2.3.4 будет соответствовать строки  132.364 а также 1a2b3c4, Вероятно, это не проблема, поскольку IP_address колонка, но такие строки могут появляться в Hostname колонка.
  • Другим является то, что, если не указано иное, grep ищет предоставленный шаблон в любом месте на линии, Таким образом, шаблон 1.2.3.4 будут соответствовать строкам, содержащим 31.2.3.4 а также 1.2.3.42,

Но я считаю, что вы хорошо поработаете над тем, чтобы получить нужную вам линию - и только эта строка - с помощью команды

grep "^1.2.3.4[[:space:]]" db

где

  • «^«Это другой символ, который является особым в регулярных выражениях; это означает, что этот шаблон должен появиться в начале строки.
  • «[[:space:]]"Представляет собой пробельный символ; либо пробел, либо вкладку. Если вы уверены, что ваш db файл использует только пробелы, вы можете просто найти пробел; например.,

    grep "^1.2.3.4 " db
    

Они все равно найдут строки, которые начинаются с 132.364 или 1a2b3c4, Но если ваш db файл правильно структурирован, у вас не должно быть таких строк в начале строк в вашем db файл.

Вы можете предотвратить "."От сопоставления произвольных символов с любым из следующих:

  • grep "^1\.2\.3\.4[[:space:]]" db
  • grep "^1\.2\.3\.4 " db
  • grep -F "1.2.3.4 " db

но первые два потребуют от вас прыгать через обручи в вашем скрипте для преобразования 1.2.3.4 в 1\.2\.3\.4, и третий убирает особое значение "^" (так 31.2.3.4 все равно совпадут).

Как указано выше, эти команды соответствуют всем линия из db файл который соответствует IP-адресу. Чтобы получить только имя хоста (второй столбец), используйте

grep "^1.2.3.4[[:space:]]" db | awk '{print $2}'

Это просто напишет имя хоста на стандартный вывод (обычно на экране). Более полезная операция в скрипте будет

db_host=$(grep "^1.2.3.4[[:space:]]" db | awk '{print $2}')

который фиксирует этот вывод в переменной оболочки db_host,

Итак, наконец, этот раздел вашего скрипта может выглядеть примерно так:

db_host = $ (grep "^ $ this_IP_address [[: space:]]" db | awk '{print $ 2}')
если ["$ db_host" = ""]
тогда
     Использовать хозяин команда.
          ︙
фи

который вы бы поставили в цикле, где переменная this_IP_address принимает каждый IP-адрес, который вы хотите обработать. Если у вас есть их в файле (т. другой файл, отдельно от db), затем прочитайте этот файл по одной строке за раз.

Например, если у вас есть IP-адреса (по одному на строку) в файле с именем src_ip, и все, что вы хотите сделать, это записать имена хостов на стандартный вывод, можно сказать,

прочитав this_IP_address
делать
    db_host = $ (grep "^ $ this_IP_address [[: space:]]" db | awk '{print $ 2}')
    если ["$ db_host" = ""]
    тогда
        # Использовать хозяин команда для поиска $ this_IP_address,
        host "$ this_IP_address" | head -n 1 | awk '{print $ 5}'
    еще
        echo "$ db_host"
    фи
сделано <src_ip

grep -f src_ip db не будет особенно полезен для проблемы, которую вы описываете (если я правильно понимаю), поскольку он будет сообщать все линии в db которые соответствуют любому IP-адресу в src_ip - чтобы вы не выяснили, какие IP-адреса не были сопоставлены.


Произошел более простой способ сделать это:

awk -v this_one="$this_IP_address" '$1 == this_one {print $2}' db

который копирует переменную оболочки this_IP_address в awk переменная this_one а затем говорит: «напечатайте второе поле любой строки, первое поле которого равно this_one«. Это один процесс, а не два, и это устраняет проблему ".«Сопоставление произвольных символов. Оберните его db_host=$(…) как прежде.


6
2017-09-19 01:43



Это не то, что я ищу. Файл должен ссылаться на мой второй столбец файла db. Второй столбец - имя хоста. Файл только одного столбца (IP-адреса) должен ссылаться на файл с именем db, который имеет 2 столбца, ip hostname, Если совпадения нет, каждый ip в исходном файле должен возвращать имя хоста с помощью команды host - unixpipe
Как сделать переменную типа $ this_IP_address для включения каждой строки файла (в данном случае, каждого IP?). Также как я могу запустить команду host? Какая там точная команда? так как для этого потребуется вызвать переменную. И если я использую файл, я не должен использовать grep -f src_ip db | awk '{print $2}')?? - unixpipe
@unixpipe: Я снова обновил ответ. ... ... ... ... ... ... ... ... «Как мне запустить host команда? "А? Я думал, вы уже используете его - в вашем вопросе говорится: «Я уже делаю последнее с host ... «Почему вы спрашиваете, как использовать его сейчас? - G-Man
Ты не понял. В вашем маленьком сценарии выше, как бы вы сделали все ip в $this_IP_address разрешить с помощью команды host? - unixpipe
Я знаю, как запустить команду host, но в вашем скрипте вам нужно запустить ее на переменной. Какую переменную вы используете? - unixpipe