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
哪里
这些仍然会找到以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
仍将匹配)。
如上所述,这些命令都匹配来自与IP地址匹配的文件的整行db
。要获取主机名(第二列),请使用
grep "^1.2.3.4[[:space:]]" db | awk '{print $2}'
这只会将主机名写入标准输出(通常是屏幕)。脚本中的一个更有用的操作是
db_host=$(grep "^1.2.3.4[[:space:]]" db | awk '{print $2}')
它将输出捕获到shell变量中db_host
。
所以,最后,你的脚本的这一部分可能看起来像
db_host = $(grep“^ $ this_IP_address [[:space:]]”db | awk'{print $ 2}')
if [“$ db_host”=“”]
然后
使用 host 命令。
︙
科幻
您将放入循环中,其中变量this_IP_address
采用您要处理的每个IP地址。如果您将它们放在一个文件中(即另一个文件,与之分开db
),则一次读取该文件一行。
例如,如果您在一个名为的文件中有IP地址(每行一个)src_ip
,而您想要做的就是将主机名写入标准输出,您可以说,
同时阅读this_IP_address
做
db_host = $(grep“^ $ this_IP_address [[:space:]]”db | awk'{print $ 2}')
if [“$ db_host”=“”]
然后
#使用 host 命令查找 $ this_IP_address 。
主持人“$ this_IP_address”| 头-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
它将shell变量复制this_IP_address
到awk
变量中this_one
然后说“打印第一个字段等于的任何行的第二个字段this_one
。”这是一个过程,而不是两个过程,它消除了“ .
”匹配任意字符的问题。db_host=$(…)
像以前一样包裹它。