首先引用另一个文件的脚本


2

嗨我有一个脚本,在其中我需要从脚本生成的IP中获取主机名。该脚本将这些IP生成为1个整齐的文件,只有1列。它实际上只是IP地址(每行1个)。我有另一个名为'db'的文件,如下所示:

IP Hostname

'db'是我的数据库,它存储委托给这些IP的IP地址和主机名列表。这些是静态地址,不会改变,通常是服务器或交换机等。我需要的是脚本生成的IP地址,我想用这个数据库文件中的主机名FIRST来解决它们,如果它没有找到它,然后运行host命令。我已经在做后者,host但我真的希望它们首先来自我的db文件。最终输出只需要1个文件,其中包含1列主机名。我有一些使用awk和数组的想法,但似乎无法完全得到我需要的东西。


1
如果您发布已经存在的脚本部分,则可能会获得更具体的答案。您正在寻找的答案似乎不仅仅是提取信息的命令,而是如何利用它。
prateek61 2014年

Answers:


6

grep是一个命令,其主要目的是查看模式(或模式)的文本。它对这项任务的简单应用就是

grep 1.2.3.4 db

这将从匹配模式“ ” IP_address Hostnamedb文件中输出“ ”行1.2.3.4。请注意,我说而不是)并匹配模式 (而不是包含字符串),因为这里有几个陷阱。

  • 一个是grep,正如我所说,(默认情况下)搜索模式而不是字符串。这些模式称为正则表达式,并且有关于它们的文档世界。关于这个讨论的正则表达式最重要的事实是句号“ .”是一个匹配任何单个字符的模式。因此,例如,模式正则表达式1.2.3.4 将匹配字符串 132.3641a2b3c4。就IP_address列而言,这些可能不是问题,但这些字符串可能出现在Hostname列中。
  • 另一个是,除非另有说明,否则 在线上的任何地方grep搜索提供的模式。因此模式将匹配包含和的行。1.2.3.431.2.3.41.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.41\.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_addressawk变量中this_one 然后说“打印第一个字段等于的任何行的第二个字段this_one。”这是一个过程,而不是两个过程,它消除了“ .”匹配任意字符的问题。db_host=$(…)像以前一样包裹它。


这不是我想要的。该文件需要引用我的第二列db文件。第二列是主机名。只有一列(ip地址)的文件应该引用一个名为db的文件,该文件有2列ip hostname。如果没有匹配,那么我的源文件中的每个ip都应该使用host命令返回主机名
unixpipe 2014年

如何创建像$ this_IP_address这样的变量来包含文件的每一行(在这种情况下,每个IP?)。另外我如何运行主机命令?那里的确切命令是什么?因为它需要调用一个变量来做到这一点。如果我正在使用文件,我不应该使用grep -f src_ip db | awk '{print $2}')
unixpipe 2014年

@unixpipe:我再次更新了答案。...... ...... ...... ......“我怎么host办命令?”嗯?我以为你已经在使用它 - 你的问题是,“我已经在做了后者host...”你为什么要问现在如何使用它?
G-Man

你误会了。在上面的小脚本中,如何$this_IP_address使用host命令解决所有ip 问题?
unixpipe 2014年

我知道如何运行host命令,但在脚本中,您需要在变量上运行它。你使用哪个变量?
unixpipe 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.