AWK: imprime la última columna junto con el valor vacío

AWK: imprime la última columna junto con el valor vacío

Podemos imprimir la última columna de cada línea en un archivo $NFsi no conocemos el número de la última columna.

Pero la dificultad que tengo es que la última columna tiene un valor vacío.

Por ejemplo,whoComando de análisis

$ who
root     tty1         2018-01-25 09:36
root     pts/0        2018-05-30 07:39 (192.168.1.134)
root     pts/1        2018-05-28 23:12 (192.168.1.134)
root     pts/2        2018-06-01 10:01 (192.168.1.188)

Obteniendo resultado:

$ who | awk '{print $NF}'
09:36
(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

Resultado Esperado

(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

Hágame saber las posibilidades de obtener el resultado esperado en una sola línea.

EDITAR 1:El escenario anterior es sólo un ejemplo. No me gusta cambiar el delimitador para lograr el resultado.

EDITAR 2:nada (una línea de salida vacía) de las líneas que tienen menos campos que el máximo

Respuesta1

Para generar solo la última columna de filas que tienen el número máximo de columnas, puede hacer algo como:

who | awk '
  NF > max  {max = NF; output = ""}
  NF == max {output = output $NF ORS}
  END       {printf "%s", output}'

Para generar una fila por cada fila de entrada, pero vacía para las filas que no tienen el número máximo de columnas:

who | awk '
  NF > max {max = NF}
  {n[NR] = NF}
  NF == max {last[NR] = $NF}
  END {for (i = 1; i <= NR; i++) print n[i] == max ? last[i] : ""}'

Respuesta2

Si desea el último campo solo de las líneas que tienen la mayor cantidad de campos, deberá leer los datos dos veces: una para averiguar el mayor número de campos y otra para imprimir los campos. Leer solo una vez no es suficiente: cualquier línea podría tener más campos que las anteriores, y no hay forma de saberlo.

Con awk(tenga en cuenta que el nombre del archivo se proporciona dos veces):

awk -vfields=0 'FNR==NR {if (NF > fields) fields=NF; next} 
     NF >= fields { print $NF } NF < fields {print ""}' file file

si filecontiene

foo bar
one two three four
1 2 3
a b c d

esto imprime el cuarto campo, o está vacío para las líneas que no lo tienen:

cuatro

d

Eso, por supuesto, no funciona con una tubería, tendrás que usar un archivo temporal.

Una solución alternativa podría almacenar en caché los campos que se van a imprimir hasta que aparezca una línea con más campos, como enLa respuesta de Stéphane.

Respuesta3

Compruebe si el quinto campo coincide \(.*\)e imprímalo si coincide.

who | awk '$5 ~ /\(.*\)/{print $5}'

Si solo está interesado en iplas direcciones, cambie la expresión regular:

who |  awk '$5 ~ /\((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\)/{print $5}'

Respuesta4

Si sólo desea obtener la última columna si esta columna está disponible, utilice el hecho de que las líneas quenoQuiero tener sólo cuatro columnas:

who | awk 'NF > 4 { print $NF }'

o, para obtener datos similares,

w -hi | awk '{ print $3 }'

información relacionada