Bash脚本将ipv4地址与正则表达式匹配

时间:2019-02-20 20:34:28

标签: bash

尝试仅获取$networks变量中具有ipv4地址的行。

#!/bin/bash

ivp4_pattern='/^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/igm'
networks=$(ip addr | grep "inet" | awk '{print $2}')

while read -r line; 
do
    echo "$line"
done <<< "$networks"

echo "$ivp4_pattern"
echo "$networks" | grep "$ivp4_pattern"

输出:

[jonathan@localhost ~]$ ./script.sh 
127.0.0.1/8
::1/128
172.16.155.128/24
fe80::da84:977a:d654:7716/64
/^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/igm

尝试删除/并与-E ...

#!/bin/bash

ivp4_pattern="'^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$'"
networks=$(ip addr | grep "inet" | awk '{print $2}')

while read -r line; 
do
    echo "$line"
done <<< "$networks"

echo $ivp4_pattern
echo $networks | grep -E $ivp4_pattern

还尝试逐行遍历网络,并将正则表达式从变量中取出...

#!/bin/bash

networks=$(ip addr | grep "inet" | awk '{print $2}')

while read -r line; 
do
    echo "$line"
done <<< "$networks"

while read -r line;
do
    echo $line
    echo $line | grep '^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$'
done <<< "$networks"

我在-grep中添加-E而没有在变量中使用正则表达式...却能正常工作吗?它不喜欢将正则表达式包含在变量中吗?

#!/bin/bash

networks=$(ip addr | grep "inet" | awk '{print $2}')

while read -r line; 
do
    echo "$line"
done <<< "$networks"

while read -r line;
do
    # echo $line
    echo $line | grep -E '^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$'
done <<< "$networks"
~                             

2 个答案:

答案 0 :(得分:1)

作为bash解决方案,如何:

ipv4_pattern="([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})"
ip addr | while read -r line; do
    if [[ $line =~ inet\ $ipv4_pattern ]]; then
        echo "${BASH_REMATCH[1]}"
    fi
done

请注意,上面的while循环是在子进程中调用的, 父级无法访问此处分配的变量。 在这种情况下,请使用流程替代;

ipv4_pattern="([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})"
while read -r line; do
    if [[ $line =~ inet\ $ipv4_pattern ]]; then
        echo "${BASH_REMATCH[1]}"
        # do some assignments here as ip_list+=("${BASH_REMATCH[1]}")
    fi
done < <(ip addr)

希望这会有所帮助。

答案 1 :(得分:1)

如果您只想列出IPv4地址,该怎么办?

第一个...

#!/bin/bash

#
# ip addr         : list IP info. 
# grep "inet "    : Only for IPv4. IPv6 addresses are listed up with "inet6".
# awk '{print $2}': Extract IPv4 adress
ipaddrs=$(ip addr | grep "inet " | awk '{print $2}')

while read -r ipaddr
do
  echo $(cut -d"/" -f1 <<< ${ipaddr})
done <<< "${ipaddrs}"

exit 0

第二个是...

#!/bin/bash

#
# ip addr         : list IP info. 
# grep "inet "    : Only for IPv4. IPv6 addresses are listed up with "inet6".
ipaddrs=$(ip addr | grep "inet ")

while read -r ipaddr
do
    # sample: inet 100.52.62.173/24 brd 100.52.62.255 scope global bond1
    ipv4_cidr=$(cut -d" " -f2 <<< ${ipaddr})
    ipv4=$(cut -d"/" -f1 <<< ${ipv4_cidr})
    netmask=$(cut -d"/" -f2 <<< ${ipv4_cidr})
    brdcast=$(cut -d" " -f4 <<< ${ipaddr})

    echo "----------------------------"
    echo "============================"
    echo "ip addr   : ${ipaddr}"
    echo "----------------------------"
    echo "IP Address: ${ipv4}"
    echo "Netmask   : ${netmask}"
    echo "Broadcast : ${brdcast}"

done <<< "${ipaddrs}"

exit 0

第三个是...

#!/bin/bash

#
# ip addr         : list IP info. 
# grep "inet "    : Only for IPv4. IPv6 addresses are listed up with "inet6".
ipaddrs=$(ip addr | grep "inet ")

while IFS=" " read -ra ipaddr
do
    # If a first line is "inet 100.52.62.173/24 brd 100.52.62.255 scope global bond1"
    # 1. ipadddr is (inet 100.52.62.173/24 brd 100.52.62.255 scope global bond1)
    # A second is cidr.
    IFS="/" read -ra ipv4_cidr <<< "${ipaddr[1]}"
    # 2. ipv4_cidr is ("100.52.62.173" "24")
    ipv4="${ipv4_cidr[0]}"
    netmask="${ipv4_cidr[1]}"
    # A fourth is 'broadcast'.
    brdcast="${ipaddr[3]}"

    echo "----------------------------"
    echo "============================"
    echo "ip addr   : ${ipaddr[@]}"
    echo "----------------------------"
    echo "IP Address: ${ipv4}"
    echo "Netmask   : ${netmask}"
    echo "Broadcast : ${brdcast}"

done <<< "${ipaddrs}"

exit 0