我有一个循环设置来输入一个包含IP列表的文件。循环将使用IP搜索文件以获取关联的MAC地址。有时,对于每个IP,将列出多个MAC。它可以是一个,也可以是七个或更多。那真是个未知数。我所知道的是,我需要能够比较每个IP报告的MAC数量,并且如果它们不匹配则会回显一些MAC。这是我的脚本输出现在的样子:
Testing 192.168.17.25
00:0f:XX:41:e7:50; 00:0f:XX:41:e7:50; 00:0f:XX:41:e7:50;
Testing 192.168.17.26
00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0;
这是我的while循环:
cat $list | while read line;
do
echo "Testing $line"
var=$(/bin/grep -A 10 -w $line $file | /bin/grep 'ethernet' | /bin/awk '{print $3}')
echo $var
done
如何构建一个if / then进入循环内部来比较MAC地址并回显一条消息,如果它找到一个不同的消息?
更新:$ list文件是一个带IP的简单文本文件。
192.168.17.1
192.168.17.2
等...
我运行IP的$文件获取MAC是一个DHCP租约文件。
lease 192.168.17.28 {
starts 2 2016/07/12 07:36:15;
ends 3 2016/07/13 07:36:15;
tstp 3 2016/07/13 07:36:15;
tsfp 3 2016/07/13 19:36:15;
atsfp 3 2016/07/13 19:36:15;
cltt 2 2016/07/12 07:36:15;
binding state free;
hardware ethernet 84:7b:eb:24:87:ef;
uid "\001\204{\353$\207\357";
更新:@ pakistanprogrammerclub
当我运行脚本时,我得到:
[root@localhost]# ./genipmacs.sh < leasesfile > ipmaclist
awk: cmd. line:2: {ipmac[$1][$2]=1}
awk: cmd. line:2: ^ syntax error
awk: cmd. line:6: for(mac in ipmac[ip])
awk: cmd. line:6: ^ syntax error
不确定这里有什么需要。是否需要将其他内容括在引号中?
更新#2 @ pakistanprogrammerclub
使用修改后的awk代码后,脚本按预期运行没有错误。但是,我的ipmaclist文件如下所示:
192.168.17.25 1 00:0
00:0 4164 192.168.17.26
192.168.17.27 1 192.168.17.28
00:0 4164 192.168.17.29 192.168.17.30
由于某些原因它没有获得MAC。我想我只需要在代码中调整grep和sed命令。这似乎是根本原因。在脚本之外运行那些产生上面看到的数据,然后awk尝试解析它。 Grep和sed外部脚本:
x.x.x.x x.x.x.x. 00:0
x.x.x.x. 00:0
x.x.x.x. 48:
x.x.x.x x.x.x.x 48:
x.x.x.x. 00:0
似乎是让写行只是切断了mac。
更新#3
新的ipmaclist内容:
00:0f:94:43:fd:d0 2 x.x.x.x
x.x.x.x. 1 dc:37:14:82:a2:82
x.x.x.x. 1 00:0f:94:41:d4:d0
x.x.x.x 1 00:0f:94:41:9f:e0
租赁档案 -
x.x.x.x
x.x.x.x
x.x.x.x
x.x.x.x
更新4
新代码也可以反向运行。
00:0f:94:c1:31:20 1 192.168.17.26
00:0f:94:c1:1f:30 3 192.168.17.27 192.168.17.28 192.168.17.29
00:0f:94:66:84:f0 1 192.168.17.30
答案 0 :(得分:2)
不要手动循环使用它们,而是考虑使用sort -u
删除重复项,然后使用wc -l
进行计数。
unique_mac_addrs() {
# First, split them up to individual lines, stripping out
# any stray spaces or blank lines, then sort and count.
echo "$@" | tr \; $'\n' | awk '$1{print $1}' | sort -u | wc -l
}
sample1="00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0;"
sample2="00:0f:XX:43:7a:f0; FF:0f:XX:43:7a:f0; EE:0f:XX:43:7a:f0; 00:0f:XX:43:7a:f0;"
unique_mac_addrs $sample1 # => 1
unique_mac_addrs $sample2 # => 3
答案 1 :(得分:2)
这种方法使用gawk 4.0生成一个以制表符分隔的MACS列表,并从租约文件中为每个IP计数 - 称之为ipmacslist:
10.0.1.1 1 00:11:22:33:44:55
10.0.1.2 2 00:11:22:33:44:56 00:11:22:37:44:56
10.0.1.3 1 00:11:22:33:44:57
你可以在$ list中为你的IP列表grep ipmacslist然后过滤计数:
grep -F -f$list ipmacslist|awk '$2 > 1'
这是生成ipmacslist的代码 - 这是一个管道 - 把它放在一个脚本中说genipmacs.sh并在stdin上提供租约文件内容 - ./genipmacs.sh <leasefile.leases >ipmacslist
# grep ip and mac from lease file
grep -Po '^lease \K[0-9.]*|hardware ethernet \K[0-9:a-f]*'|
# join pairs of consecutive lines to get ip-mac pair on one line
sed -n 'N; s/\n/\t/;p'|
# collect unique ip-mac pairs - output ip unique macs list and count
# uses gawk 4.0 2D arrays
awk '
# bail on invalid input
!/^[0-9.]+\t[0-9:a-f]+/ {
printf("error line %d not IP-MAC pair: \"%s\"\n", NR, $0)
exitstatus=1
exit exitstatus
}
{ipmac[$1][$2]=1}
END {
if(exitstatus) exit exitstatus
for(ip in ipmac) {
printf("%s\t%d", ip, length(ipmac[ip]))
for(mac in ipmac[ip])
printf("\t%s", mac)
printf("\n")
}
}
'
答案 2 :(得分:1)
Pre-gawk 4.0解决方案使用假的2D阵列 - 这很痛苦 - 请升级到gawk 4.0 - 它已经有几年了 -
# grep ip and mac from lease file
grep -Po '^lease \K[0-9.]*|hardware ethernet \K[0-9:a-f]*'|
# join pairs of consecutive lines to get ip-mac pair on one line
sed -n 'N; s/\n/\t/;p'|
# collect unique ip-mac pairs - output ip unique macs list and count
awk '
# bail on invalid input
!/^[0-9.]+\t[0-9:a-f]+/ {
printf("error line %d not IP-MAC pair: \"%s\"\n", NR, $0)
exitstatus=1
exit exitstatus
}
{
if(($1, $2) in ipmac) next
if($1 in macs) {
macs[$1]=macs[$1] "\t" $2
} else {
ips[i++]=$1
macs[$1]=$2
}
++nmacs[$1]
ipmac[$1, $2]=1
}
END {
if(exitstatus) exit exitstatus
for(i=0; i < length(ips); ++i) {
ip=ips[i]
printf("%s\t%d", ip, nmacs[ip])
printf("\t%s\n", macs[ip])
}
}
'
其输出和测试租用文件如下
10.0.1.1 1 00:11:22:33:44:55
10.0.1.2 2 00:11:22:33:44:56 00:11:22:37:4f:56
10.0.1.3 2 00:11:22:33:44:57 00:11:22:a3:44:57
测试租约文件
lease 10.0.1.1 {
starts 5 2015/05/15 01:57:17;
ends 5 2015/05/15 02:07:17;
tstp 5 2015/05/15 02:07:17;
cltt 5 2015/05/15 01:57:17;
binding state free;
hardware ethernet 00:11:22:33:44:55;
client-hostname "host1";
uid "foo";
}
lease 10.0.1.2 {
starts 5 2015/05/15 02:09:16;
ends 5 2015/05/15 02:19:16;
tstp 5 2015/05/15 02:19:16;
cltt 5 2015/05/15 02:09:16;
binding state free;
hardware ethernet 00:11:22:33:44:56;
client-hostname "host2";
uid "bar";
}
lease 10.0.1.3 {
starts 5 2015/05/15 02:16:01;
ends 5 2015/05/15 02:26:01;
tstp 5 2015/05/15 02:26:01;
cltt 5 2015/05/15 02:16:01;
binding state free;
hardware ethernet 00:11:22:33:44:57;
client-hostname "host3";
uid "baz-1";
}
lease 10.0.1.3 {
starts 5 2015/05/15 02:17:01;
ends 5 2015/05/15 02:27:01;
tstp 5 2015/05/15 02:27:01;
cltt 5 2015/05/15 02:17:01;
binding state free;
hardware ethernet 00:11:22:a3:44:57;
client-hostname "host3";
uid "baz-2";
}
lease 10.0.1.2 {
starts 5 2015/05/15 02:09:16;
ends 5 2015/05/15 02:19:16;
tstp 5 2015/05/15 02:19:16;
cltt 5 2015/05/15 02:09:16;
binding state free;
hardware ethernet 00:11:22:37:4f:56;
client-hostname "host2";
uid "bar-1";
}