Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash While循环输出多值比较,如果不同,则返回消息_Bash_If Statement_While Loop - Fatal编程技术网

Bash While循环输出多值比较,如果不同,则返回消息

Bash While循环输出多值比较,如果不同,则返回消息,bash,if-statement,while-loop,Bash,If Statement,While Loop,我有一个循环设置来输入一个包含IP列表的文件。循环将使用IP搜索文件以获取相关的MAC地址。有时,每个IP都会列出多个MAC。可能是一个,也可能是七个或更多。这真是个未知数。我所知道的是,我需要能够比较每一个IP报告了多少个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

我有一个循环设置来输入一个包含IP列表的文件。循环将使用IP搜索文件以获取相关的MAC地址。有时,每个IP都会列出多个MAC。可能是一个,也可能是七个或更多。这真是个未知数。我所知道的是,我需要能够比较每一个IP报告了多少个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的$file是一个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
由于某种原因,它没有得到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

新IPMAC列表内容:

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

<>而不是用手工循环遍历它们,考虑使用<代码>排序-U/COD>删除重复,然后<代码> 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

<>而不是用手工循环遍历它们,考虑使用<代码>排序-U/COD>删除重复,然后<代码> 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

此方法使用gawk 4.0生成一个以选项卡分隔的MAC列表,并从租约文件中为每个IP计数-称之为IPMAC列表:

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
您可以grep ipmacslist以$list的形式列出IP列表,然后根据计数进行筛选:

grep -F -f$list ipmacslist|awk '$2 > 1'
下面是生成ipmacslist的代码-这是一个管道-将其放入脚本(比如genipmacs.sh)中,并将租约文件内容输入stdin-
/genipmacs.sh 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")
  }
}
'

此方法使用gawk 4.0生成一个以选项卡分隔的MAC列表,并从租约文件中为每个IP计数-称之为IPMAC列表:

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
您可以grep ipmacslist以$list的形式列出IP列表,然后根据计数进行筛选:

grep -F -f$list ipmacslist|awk '$2 > 1'
下面是生成ipmacslist的代码-这是一个管道-将其放入脚本(比如genipmacs.sh)中,并将租约文件内容输入stdin-
/genipmacs.sh 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")
  }
}
'

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])
  }
}
'
测试租赁文件

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";
}

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])
  }
}
'
测试租赁文件

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";
}


你能举一个你的原始文件格式的例子吗?是的,给我一些。刚刚更新。为什么不把
var
做成一个索引数组,在
/bin/awk'{print$3}'
之后添加
|sort-u
,例如
var=($(你的东西| sort-u))
然后
${var[@]}
告诉你有多少个独特的Mac,然后
回显“${var[@]}”列出它们,或者你可以在$var[}中为i做
;做回显“$i”;完成
。这就是我最后要做的。我保持一切不变,只是在var变量的末尾添加了sort-u。现在我知道如果我看到多个MAC,我会有一个重复的IP。您在问题中显示的错误来自
awk
告诉您它不知道
[…][…]
的含义。
awk
中的多维数组与
[…,…]
一起使用。另外,你没有向我们展示代码的这一部分。你能举一个你原始文件格式的例子吗?是的,给我一些。刚刚更新。为什么不把
var
做成一个索引数组,在
/bin/awk'{print$3}'
之后添加
|sort-u
,例如
var=($(你的东西| sort-u))
然后
${var[@]}
告诉你有多少个独特的Mac,然后
回显“${var[@]}”列出它们,或者你可以在$var[}中为i做
;做回显“$i”;完成
。这就是我最后要做的。我保持一切不变,只是在var变量的末尾添加了sort-u。现在我知道如果我看到多个MAC,我会有一个重复的IP。您在问题中显示的错误来自
awk
告诉您它不知道
[…][…]
的含义。
awk
中的多维数组与
[…,…]
一起使用。另外,你没有向我们展示代码的这一部分。你能详细解释一下吗,因为你把我弄丢了。循环是我获取MAC的方式,在您的示例中,我没有看到引用的文件。这是为了在您已经拥有的文件之后进行的,而不是在bash中编写的内部循环。换句话说,一旦你已经得到了问题中的代码生成行,这些行看起来像我的
sample
行,你就可以使用我的函数将它们后处理为结果。你能详细解释一下吗,因为你把我弄丢了。循环是我获取MAC的方式,在您的示例中,我没有看到引用的文件。这是为了在您已经拥有的文件之后进行的,而不是在bash中编写的内部循环。换句话说,一旦你已经得到了问题中的代码,生成了看起来像我的
示例
行的行,你可以使用我的函数将它们后处理为结果。我在代码中没有看到任何东西告诉它在哪里可以找到我的租约文件?在您的grep命令中,$list变量是什么?$list是您自己的变量,其中包含要检查的IP列表的文件-代码是一个管道-在stdin上向其提供租约文件内容-您可以修改它,以其他方式读取租约文件。我在运行脚本时遇到一些错误。我将更新我的帖子以添加