awk从regexp中多次排除

时间:2013-02-16 08:50:16

标签: regex bash awk

我有一个小文件:

    # Format
    # <iface_name>,<ip_addr>,<ip_netmask>,<broadcast>,<eth_addr>,<status>,<obtaining_method>

    eth0,192.168.0.11,255.255.255.0,192.168.0.255,4A:DD:00:00:05:00,up,static
    lv0,172.20.8.12,255.255.248.0,172.20.15.255,4A:DD:00:FF:15:01,down,static
    #lv0:0,172.20.16.12,255.255.248.0,172.20.23.255,4A:DD:00:FF:15:01,down,static
    #lv0:1,172.20.24.12,255.255.248.0,172.20.31.255,4A:DD:00:FF:15:01,down,static
    lv1,172.21.8.11,255.255.248.0,172.21.15.255,4A:DD:00:FF:15:02,down,dhcp
    #lv1:0,172.21.16.1,255.255.248.0,172.21.23.255,4A:DD:00:FF:15:02,down,static
    #lv1:1,172.21.24.1,255.255.248.0,172.21.31.255,4A:DD:00:FF:15:02,down,static
    mv0,10.100.0.1,255.255.255.0,10.100.0.255,40:FD:00:00:01:0A,up,static
    lp0,172.22.0.12,255.255.255.0,172.22.0.255,4A:DD:00:FF:15:04,down,static
    lp1,172.22.1.12,255.255.255.0,172.22.1.255,4A:DD:00:FF:15:05,down,static
    dummy0,192.168.111.100,255.255.255.0,192.168.111.255,00:00:00:00:00:00,down,static

我有一个想法是在一个周期内获取所有接口参数并创建了这个表达式:

    #!/bin/sh

    SPATH=/mnt/dcu/tmp/

    for INTERFACE in $(awk -F\, '/^[^#]/ {print $1}' $SPATH/ifaces); do
        INTERFACE_SETTINGS=$(awk -F\, '$1 ~ interface_name {print $2,$3,$4,$5,$6,$7}' interface_name=$INTERFACE $SPATH/ifaces)
        set $INTERFACE_SETTINGS
        IPADDR=$1
        NETMASK=$2
        BROADCAST=$3
        MACADDR=$4
        STATE=$5
        METHOD=$6

        sed -r -i -e "/$INTERFACE/s/^([^,]*,)([^,]*,)([^,]*,)([^,]*,)([^,]*,)([^,]*,)([^,]*)$/$INTERFACE,$IPADDR,$NETMASK,$BROADCAST,$MACADDR,$STATE,$METHOD/" /etc/network/ifaces
    done

但它执行以下操作:

     # Format
     # <iface_name>,<ip_addr>,<ip_netmask>,<broadcast>,<eth_addr>,<status>,<obtaining_method>

     eth0,192.168.0.11,255.255.255.0,192.168.0.255,4A:DD:00:00:05:00,up,static
     lv0,172.20.8.12,255.255.248.0,172.20.15.255,4A:DD:00:FF:15:01,down,static
     lv0,172.20.8.12,255.255.248.0,172.20.15.255,4A:DD:00:FF:15:01,down,static
     lv0,172.20.8.12,255.255.248.0,172.20.15.255,4A:DD:00:FF:15:01,down,static
     lv1,172.21.8.11,255.255.248.0,172.21.15.255,4A:DD:00:FF:15:02,down,dhcp
     lv1,172.21.8.11,255.255.248.0,172.21.15.255,4A:DD:00:FF:15:02,down,dhcp
     lv1,172.21.8.11,255.255.248.0,172.21.15.255,4A:DD:00:FF:15:02,down,dhcp
     mv0,10.100.0.1,255.255.255.0,10.100.0.255,40:FD:00:00:01:0A,up,static
     lp0,172.22.0.12,255.255.255.0,172.22.0.255,4A:DD:00:FF:15:04,down,static
     lp1,172.22.1.12,255.255.255.0,172.22.1.255,4A:DD:00:FF:15:05,down,static
     dummy0,192.168.111.100,255.255.255.0,192.168.111.255,00:00:00:00:00:00,down,static

它得到了更改以及已注释的接口。

我试图为它做任何例外 - 但它不适用于一行:

    awk -F\, '{ if ($1 !~ /[#]|^$/interface_name ) {print $2,$3,$4,$5,$6,$7} }' interface_name=lv0 /etc/network/ifaces
    192.168.0.1 255.255.255.0 192.168.0.255 4A:DD:00:00:01:0A up static
    172.20.8.1 255.255.248.0 172.20.15.255 4A:DD:00:FF:15:01 up static
    172.21.8.1 255.255.248.0 172.21.15.255 4A:DD:00:FF:15:02 down static
    10.10.0.1 255.255.255.0 10.10.0.255 40:FD:00:00:01:0A down static
    172.22.0.1 255.255.255.0 172.22.0.255 4A:DD:00:FF:15:04 down static
    172.22.1.1 255.255.255.0 172.22.1.255 4A:DD:00:FF:15:05 down static
    192.168.111.111 255.255.255.0 192.168.111.255 00:00:00:00:00:00 down static

我如何为我的案子做这件事?

提前谢谢。

3 个答案:

答案 0 :(得分:2)

你已经在使用awk了,为什么要添加一个shell循环和一个sed命令?

看起来你要做的就是将/ etc / network / ifaces中的值替换为具有相同接口名称的$ SPATH / ifaces中的值。如果是这样,整个事情只是:

awk -F, 'NR==FNR{a[$1]=$0; next} {print ($1 in a ? a[$1] : $0}' $SPATH/ifaces /etc/network/ifaces > tmp && mv tmp /etc/network/ifaces

看起来注释行和空白行不会成为问题,因为它们只在文件无关紧要时匹配(空白是空白且每个文件中的前几行是相同的,并且没有在第二个文件中注释掉了“真正的”数据行)但如果他们这样做,那么只需调整它就可以在解析第一个文件时排除它们:

awk -F, 'NR==FNR{if (!/^(#|$)/) a[$1]=$0; next} {print ($1 in a ? a[$1] : $0}' $SPATH/ifaces /etc/network/ifaces > tmp && mv tmp /etc/network/ifaces

答案 1 :(得分:1)

要根据awk变量匹配bash中的模式,您可以执行以下操作:

awk -v interface_name=$inter '$0 ~ interface_name {print $0}' inputfile

此命令将bash变量$inter传递给awk变量interface_name(注意-v选项),然后过滤包含变量中sting的所有行(带{ {1}})

答案 2 :(得分:0)

以这种方式做到了,但非常感谢用户 user000001

    awk -F\, '{ if ($1 !~ /[#]|^$/interface_name  && $1 ~ interface_name) {print $2,$3,$4,$5,$6,$7} }' interface_name=lv0 /etc/network/ifaces
    172.20.8.1 255.255.248.0 172.20.15.255 4A:DD:00:FF:15:01 up static