shell - Cómo modificar la entrada de ifconfig en awk

CorePress2024-01-24  9

Editar: Salida de muestra de ifconfig

enp2s0f1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 2540  bytes 207824 (202.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2540  bytes 207824 (202.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask xxx.xxx.xxx.x  broadcast xxx.xxx.xxx.xxx
        inet6 xxxx::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 1413004  bytes 634560717 (605.1 MiB)
        RX errors 0  dropped 2  overruns 0  frame 0
        TX packets 279420  bytes 36406046 (34.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Tengo este bonito código escrito por otro usuario útil y necesito modificar su salida. Debo admitir que me cuesta hacerlo.

ifconfig |
awk '
/^[[:alnum:]]+: / {
   n = 
   p = 1
}
n !~ /^lo/ && /^[[:blank:]]+(inet|ether) / {
   if (p) {
      print n
      p = 0
   }
   print , 
}'

Aquí está el resultado correcto:

enp2s0f1:
ether xx:xx:xx:xx:xx:xx
wlp3s0:
inet xxx.xxx.xxx.xxx
ether xx:xx:xx:xx:xx:xx

Y así es como necesito que se modifique:

(con las columnas creadas inet_name, ip_address, mac_address)

inet_name ip_address           mac_address
enp2s0f1:                      ether xx:xx:xx:xx:xx:xx
wlp3s0:   inet xxx.xxx.xxx.xxx ether xx:xx:xx:xx:xx:xx

Quizás los arreglos AWK explicados con 5 ejemplos prácticos le darán algunas ideas con las que trabajar.

- Ted Lyngmo

27 de marzo de 2021 a las 10:28

Por favor, publique el resultado de muestra de ifconfig.

- James Brown

27/03/2021 a las 10:35



------------------------------------

Puedes probar este awk:

ifconfig |
awk -v OFS='\t' 'BEGIN {ip=mac=" "; print "inet_name", "ip_ddress", "mac_address"} /^[[:alnum:]]+: / {if (inet) {print inet, ip, mac; ip=mac=" "; inet=""} if ( !~ /^lo/) inet=} inet && /^[[:blank:]]+inet / {ip= " " } inet && /^[[:blank:]]+ether / {mac= " " } END {if (inet) print inet, ip, mac}' | column -t -s $'\t'

inet_name  ip_ddress             mac_address
enp2s0f1:                        ether xx:xx:xx:xx:xx:xx
wlp3s0:    inet xxx.xxx.xxx.xxx  ether xx:xx:xx:xx:xx:xx

Para hacerlo más legible:

ifconfig |
awk -v OFS='\t' '
# set output field separator to tab
BEGIN {
   # initialize ip and mac variables
   ip = mac = " "
   print header record
   print "inet_name", "ip_ddress", "mac_address"
}
/^[[:alnum:]]+: / {            # if no blank at start
   if (inet) {                 # print full record if not first time
      print inet, ip, mac
      ip = mac = " "           # reset variables
      inet = ""
   }
   if ( !~ /^lo/)            # if not starting with "lo"
      inet =                 # save inet name in var inet
}
inet && /^[[:blank:]]+inet / { # if inet is set and we have inet after spaces
   ip =  " "               # save  " "  in ip variable
}
inet && /^[[:blank:]]+ether / {#  if inet is set and we have ether after spaces
   mac =  " "              # save  " "  in mac variable

}
END {
   if (inet)                   # if inet is not blank
      print inet, ip, mac      # print full record
}
' | column -t -s $'\t'
El comando de columna se ha utilizado para la salida tabular.

3

1

¡Guau! ...¡y aquí estás para salvar el día otra vez! Gracias hombre, todavía es demasiado complicado para mí. ¿Podrías colocar comentarios como la última vez? :D

- kamil_debski

27/03/2021 a las 11:04

Claro, agregándolo ahora

- anubhava

27/03/2021 a las 11:05

1

¡Muchas gracias! Me sumergiré en ello y lo analizaré para comprender mejor lo que está pasando.

- kamil_debski

27/03/2021 a las 11:21



------------------------------------

En lugar de analizar la salida de ifconfig, que no es un intercambio de datos API confiable, puede usar la herramienta ip con su opción -j o -json para generar una respuesta con formato JSON que se puede analizar de manera confiable con una herramienta como jq o cualquier lenguaje de programación con un analizador JSON.

Aquí está como una sola línea:

ip -json addr show |
  jq -r '"name\tip_address\tmac_address", ( .[] | if (.addr_info | length) > 0 then .ifname + "\t" + (.addr_info[] | select(.family=="inet")).local + "\t" + .address else empty end )'

O script jq independiente comentado:

#!/usr/bin/env -S jq -rf

# Print header line
"name\tip_address\tmac_address",
(
  # Stream all results array
  .[] |

  # If interface has a non-empty addr_info array
  if (.addr_info | length) > 0
  then
    # Print interface name as first column
    .ifname + "\t" + (
    # Print ipv4 address as second column
      .addr_info[] | select(.family=="inet")
    ).local + "\t" +
    # Print mac address as third column
    .address
  else
  # Do nothing if interface has no ip address
    empty
  end
)

Ejemplosalida:

name    ip_address      mac_address
lo      127.0.0.1       00:00:00:00:00:00
enp4s0  192.168.1.10    00:24:1d:00:00:00
virbr0  192.168.122.1   52:54:00:00:00:00

1

Gracias, eso también es útil. Pero necesito hacerlo de la manera más difícil. :(

- kamil_debski

27/03/2021 a las 16:09

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare