Retornando a saída do Perl Regex

1

Estou tentando apenas retornar os valores inet dos adaptadores UP em ip addr ,

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:19:21:f5:04:42 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global enp0s7
       valid_lft forever preferred_lft forever
    inet6 fe80::4672:94c8:d31b:a04a/64 scope link
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 52:54:00:29:38:4d brd ff:ff:ff:ff:ff:ff

Eu tenho esse regex para encontrar isso, mas ele retorna toda a linha, como é esperado com o grep:

([0-9]+:.{1,}state UP.{1,}(\n.{1,}?){1,}inet )\K([0-9]{1,3}\.?){4}

retorna isso:

inet 192.168.1.100/24 brd 192.168.1.255 scope global enp0s7

O que eu quero é que apenas retorne 192.168.1.100 (o IP após inet ). O grep pode fazer isso de alguma forma, e se não, qual é a maneira correta de fazer isso?

EDIT: OK, aqui está a parte relevante do roteiro:

NUMOFNETWORKADAPTERS="$(ip addr | grep -Pc '[0-9]{1}: ')"
IPOFACTIVEADAPTER="$(ip addr | grep -Pc '(?<=state UP(.+\n){2,$NUMOFNETWORKADAPTER}?    inet )[^/]{1,15}')"

echo "LOCAL IP: $IPOFACTIVEADAPTER"

Mas isso gera um erro lookbehind assertion is not fixed length .

    
por Trevor Sears 24.07.2016 / 17:04

2 respostas

2

grep pode não ser a melhor opção aqui, embora com um PCRE habilitado grep e -o um possa capturar os endereços IP com uma correspondência lookbehind de largura zero para localizar inet e depois corresponder ao IP seguinte isso.

ip addr | grep -Po '(?<=inet )[^/]+'

Para o problema de várias linhas de "get inet addr de dispositivos que estão ativos", algo como

ip link | awk -F: '/state UP/{print $2}' \
| while read updev; do \
  ip addr show $updev | grep -Po '(?<=inet )[^/]+'; done

pode ser mais adequado.

    
por 24.07.2016 / 17:24
1

Na verdade, o regexp

([0-9]+:.{1,}state UP.{1,}(\n.{1,}?){1,}inet )\K([0-9]{1,3}\.?){4}

que você apresentou pela primeira vez, funciona , com um ambiente apropriado e Perl:

$ perl -l -0 -ne 'print $& if /([0-9]+:.{1,}state UP.{1,}(\n.{1,}?){1,}inet )\K([0-9]{1,3}\.?){4}/'  < output_of_your_ip_addr
192.168.1.100

-0 lê o arquivo inteiro (em vez de linha por linha), e $& contém a parte correspondente (o que resta depois que \K derruba a parte esquerda).

Embora se o Perl seja utilizável, eu apenas escreveria

ip addr | perl -l -0ne  'print $1 while /state UP.*?inet ([0-9.]+)/sg'

para imprimir todas as correspondências. (Altere while para if para obter apenas a primeira correspondência. $1 contém o que correspondeu a primeira () .)

    
por 24.07.2016 / 19:37