从字符串数组中选择有效的IP

时间:2018-07-29 15:15:38

标签: arrays bash ip-address

在我的用例中,我要从列表中过滤某些IPv4,并将它们放入数组中以执行进一步的任务:

Connection Reset

结果是:

readarray -t firstarray < <(grep -ni '^ser*' IPbook.file | cut -f 2 -d "-")

如您所见,最后一行不是IP,因此我迫切希望在FIRSTARRAY上添加一些正则表达式检查。 我不想保存抵押文件以与它们一起使用,因此我正在寻找一些“即时”选项来正则表达式firstarray。我尝试了以下方法:

10.8.61.10
10.0.10.15
172.0.20.30
678.0.0.10

但是在输出中,我看到系统认为$ X是一个文件/目录,即使它清楚地看到了它,也没有处理该值:

for X in "${FIRSTARRAY[@]}"; do
  readarray -t SECONDARRAY < <(grep -E '\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b' "$X")
done

我做错了什么,什么是最好的方法?

2 个答案:

答案 0 :(得分:2)

您正在将"$X"作为参数传递给grep,因此将其视为文件。请改用herestring <<<

for X in "${firstarray[@]}"; do
  readarray -t secondarray < <(grep -E '\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b' <<< "$X")
done

最好编写一个验证IP的函数,而不是仅仅依靠regex match

#!/bin/bash
validate_ip() {
  local arr element
  IFS=. read -r -a arr <<< "$1"                  # convert ip string to array
  [[ ${#arr[@]} != 4 ]] && return 1              # doesn't have four parts
  for element in "${arr[@]}"; do
    [[ $element =~ ^[0-9]+$ ]]       || return 1 # non numeric characters found
    [[ $element =~ ^0[1-9]+$ ]]      || return 1 # 0 not allowed in leading position if followed by other digits, to prevent it from being interpreted as on octal number
    ((element < 0 || element > 255)) && return 1 # number out of range
  done
  return 0
}

然后遍历数组:

for x in "${firstarray[@]}"; do
  validate_ip "$x" && secondarray+=("$x") # add to second array if element is a valid IP
done

答案 1 :(得分:1)

问题是,您将参数传递给world_x, world_y命令,并且它希望读取标准输入。

您可以使用正则表达式在第一个命令中过滤IP地址:

mm

然后,您在grep中只有IP地址。