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-- )  } '

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


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) ) }'
)

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.


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


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

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


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

1

Primero disminuye el valor y luego lo imprime:

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

O

rev file|cut -d ' ' -f2|rev

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 }'

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.