在grep中找到为每个IP执行Shell脚本

时间:2013-11-17 02:00:26

标签: linux bash shell

我目前正致力于通过SNMP监控我们的接入点的脚本。问题是,如何为grep命令中找到的每个AP IP执行snmp命令。我有一个包含IP的文本文件:

O55 172.22.168.3
O55 172.22.168.8
O55 172.22.168.5
O55 172.22.168.6
O55 172.22.168.4
O55 172.22.168.7
546 172.22.98.3
546 172.22.98.4
546 172.22.98.5
546 172.22.98.6
546 172.22.98.7
546 172.22.98.8
546 172.22.98.54

现在我使用此命令仅查找特定ID,对于此示例,我发现“O55”。

grep "O55" O55.txt | awk '{print $2}' | sort

然后结果将只显示“O55”行中找到的那些IP。

172.22.168.3
172.22.168.4
172.22.168.5
172.22.168.6
172.22.168.7
172.22.168.8

现在我的问题是,我怎样才能为找到的每个IP执行我的snmpwalk命令?谁能让我知道如何启动命令?这些命令是我仅用于一个给定ip的snmpwalk命令,我只是不知道如何为找到的多个IP启动命令。

snmpwalk -v2c -c Canopy 172.22.168.3 1.3.6.1.4.1.161.19.3.3.1.1
snmpwalk -v2c -c Canopy 172.22.168.3 1.3.6.1.4.1.161.19.3.1.3.3

总结一下,我想要的结果是这样的,

输入BTSID ==> O55
然后运行脚本,在O55.txt

中找到O55
O55 172.22.168.3
O55 172.22.168.8
O55 172.22.168.5
O55 172.22.168.6
O55 172.22.168.4
O55 172.22.168.7

然后运行snmpwalk命令,但snmpwalk的每一行都有一个对应的变量,例如:

OID_A=snmpwalk -v2c -c Canopy "each_IP_of_O55" 1.3.6.1.4.1.161.19.3.3.1.1 OID_B=snmpwalk -v2c -c Canopy "each_IP_of_O55" 1.3.6.1.4.1.161.19.3.3.1.9 OID_C=snmpwalk -v2c -c Canopy "each_IP_of_O55" 1.3.6.1.4.1.161.19.3.1.4.1.49

然后最后的结果将是:

echo "${OID_A} || ${OID_B} || ${OID_C}"

结果的例子是这样的:

172.22.168.3   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync
172.22.168.8   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync
172.22.168.5   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync
172.22.168.6   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync
172.22.168.4   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync
172.22.168.7   ||   CANOPY 11.0.2 AP-DES   ||   Receiving Sync

非常感谢任何帮助。谢谢。 :)

感谢您的帮助,不知怎的,我已经成功制作了一个脚本,结果正是我想要的。感谢您的建议和意见。这是我制作的剧本的一部分

 #!/bin/bash  
 BTSID="$1"  
 SNMPWALK='/usr/bin/snmpwalk'  
 SNMPOID='1.3.6.1.4.1.161.19.3'  

 echo "Query Time: `date "+%m/%d/%Y %H:%M:%S"`"  
 APIP=`grep ${BTSID} -i O55.txt | awk '{print $2}'`  
 for EACH in `echo ${APIP}`  
  do  
  SWVersion=`$SNMPWALK -v2c -c Canopy ${EACH} ${SNMPOID}.3.1.1 | awk '{print $4" "$5" "$6}' | sed 's/"//g'`  
  Sync=`$SNMPWALK -v2c -c Canopy ${EACH} ${SNMPOID}.1.3.3 | awk '{print $4" "$5}' | sed 's/"//g'`  
  Linkspeed=`$SNMPWALK -v2c -c Canopy ${EACH} ${SNMPOID}.3.1.9 | awk '{print $4" "$5" "$6}' | sed 's/"//g'`  

  echo "${EACH}  ||  ${SWVersion}  ||  ${Sync}  ||  ${Linkspeed}  ||  ${Confsrc}:${confsrc_v}  
正如William Pursell所说的那样,“不要把grep传递给awk”,但是这个脚本产生了我需要的结果。如果您对如何使用grep piping awk改进零件有任何建议,我们非常感谢。谢谢。 :)

2 个答案:

答案 0 :(得分:1)

我不熟悉SNMP,但是在process substitution的while循环中进行bash read调用应该可以解决问题。此外,您应该能够丢失命令并让处理过滤,如下所示

while IFS= read -r ip_addr; do
 snmpwalk -v2c -c Canopy "${ip_addr}" 1.3.6.1.4.1.161.19.3.3.1.1
 snmpwalk -v2c -c Canopy "${ip_addr}" 1.3.6.1.4.1.161.19.3.1.3.3 
done < <(awk '/055/ {print $2}' O55.txt | sort)

答案 1 :(得分:0)

使用awk。如果您实际上不需要对ips进行排序,则可以直接从awk调用shell脚本。例如,如果要为文件中与第一列中的“055”字符串匹配的每个IP地址运行/path/to/script $ip

awk '$1 == "055" { system( "/path/to/script " $2 )}'

您正在调用的命令非常简单,可以直接调用它们而不是将它们放在脚本中:

awk '$1 == "055" {
        system( "snmpwalk -v2c -c Canopy " $2 " 1.3.6.1.4.1.161.19.3.3.1.1")
        system( "snmpwalk -v2c -c Canopy " $2 " 1.3.6.1.4.1.161.19.3.1.3.3")
}' 055.txt

如果你确实需要对它们进行排序,那么预先排序可能是最简单的:

sort 055.txt | awk ...

无论你做什么,都不要将grep传递给awkawk完全能够过滤数据。

如果值055在shell变量BTSID中,您可以使用以下语法将变量传递给awk:

awk '$1 == m { system( "/path/to/script " $2 )}' m=${BTSID}