grep
- команда, основная цель которой состоит в том, чтобы просматривать текст на предмет наличия паттерна (или паттернов).
Его упрощенное приложение для этой задачи будет
grep 1.2.3.4 db
который будет выводить строку IP_address Hostname
() из файла 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}')
if [ "$db_host" = "" ]
then
Use the host command.
︙
fi
который вы бы поместили в цикл, где переменная this_IP_address
принимает каждый IP-адрес, который вы хотите обработать.
Если они есть в файле (т. Е. В другом файле, отдельном от db
), прочитайте этот файл по одной строке за раз.
Например, если у вас есть IP-адреса (по одному на строку) в файле с именем src_ip
, и все, что вам нужно сделать, это записать имена хостов в стандартный вывод, вы можете сказать:
while read this_IP_address
do
db_host=$(grep "^$this_IP_address[[:space:]]" db | awk '{print $2}')
if [ "$db_host" = "" ]
then
# Use the host command to lookup $this_IP_address.
host "$this_IP_address" | head -n 1 | awk '{print $5}'
else
echo "$db_host"
fi
done < 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=$(…)
как и раньше.