
Podemos imprimir la última columna de cada línea en un archivo $NF
si 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,who
Comando 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 file
contiene
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 ip
las 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 }'