Imprima la segunda última columna / campo en awk

164

Quiero imprimir la segunda última columna o campo en awk. El número de campos es variable. Sé que debería poder usar, $NFpero no estoy seguro de cómo se puede usar.

Y esto no parece funcionar:

awk ' { print ( $NF-- )  } '
Brian G
fuente
10
NFes el último índice de campo, $NFes el valor del último campo
glenn jackman
Eso tiene sentido ahora. Por eso el dólar fuera del paréntesis funciona, supongo
Brian G

Respuestas:

279
awk '{print $(NF-1)}'

Deberia trabajar

Chris Kannon
fuente
2
Esto no funciona para mi. Obtengo "title: 5: comando no encontrado: NF-1" en awk 3.1.8 en Ubuntu.
Gurgeh
3
Evitaría la disminución previa / posterior para asegurarme de que no cambie el valor de $ NF
Gregory Patmore
Esto se rompe si intentas obtener el tercer último campo comoawk -F '.' '{print $(NF-2)}'
gies0r
3
@Gurgeh: Esto sucede porque $(..)invoca un comando en un subshell dependiendo del shell que esté utilizando. Puede solucionar esto utilizando en $ (NF-1)lugar de $(NF-1).
wting
21

Pequeña adición a la respuesta aceptada de Chris Kannon: solo imprima si realmente hay una segunda última columna.

(
echo       | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1     | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2   | awk 'NF && NF-1 { print ( $(NF-1) ) }'
echo 1 2 3 | awk 'NF && NF-1 { print ( $(NF-1) ) }'
)
progz
fuente
15

Es más simple:

 awk '{print $--NF}' 

La razón por la que el original $NF--no funcionó es porque la expresión se evalúa antes de la disminución, mientras que mi disminución de prefijo se realiza antes de la evaluación.

Steve
fuente
Como mnemónico, este comportamiento es el mismo que C / Java int x = ++i int x = i++, etc. , prefijo significa incremento primero; postfix significa incremento posterior (asignación primero).
Fin de semana del
9
awk ' { print ( $(NF-1) ) }' file
ghostdog74
fuente
4

¡No estabas lejos del resultado! Esto lo hace:

awk '{NF--; print $NF}' file

Esto disminuye el número de campos en uno, de modo que $NFcontiene el penúltimo anterior.

Prueba

Generemos algunos números e imprimámoslos en grupos de 5:

$ seq 12 | xargs -n5
1 2 3 4 5
6 7 8 9 10
11 12

Imprimamos el penúltimo en cada línea:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11
fedorqui 'así que deja de dañar'
fuente
3

Solución Perl similar a la solución awk de Chris Kannon:

perl -lane 'print $F[$#F-1]' file

Se utilizan estas opciones de línea de comandos:

  • n recorra cada línea del archivo de entrada, no imprima automáticamente cada línea

  • l elimina las nuevas líneas antes del procesamiento y las agrega nuevamente

  • amodo de división automática: divide las líneas de entrada en la @Fmatriz. Por defecto se divide en espacios en blanco

  • e ejecuta el código perl

La @Fmatriz autosplit comienza en el índice [0] mientras que los campos awk comienzan con $ 1.
$#Fes el número de elementos en@F

Chris Koknat
fuente
1
o use la indexación negativa ya proporcionada por perl ...$F[-2]
Sundeep
2

¿Intentaste comenzar de derecha a izquierda usando el comando rev? En este caso solo necesita imprimir la segunda columna:

seq 12 | xargs -n5 | rev | awk '{ print $2}' | rev
4
9
11
Fdv
fuente
1

Primero disminuye el valor y luego lo imprime:

awk ' { print $(--NF)}' file

O

rev file|cut -d ' ' -f2|rev
VIPIN KUMAR
fuente
0

Si tiene muchas columnas y desea imprimir todas pero no las tres nubes en la última, entonces esto podría ayudar

awk '{ $NF="";$(NF-1)="";$(NF-2)="" ; print $0 }'

Arena1512
fuente