Stampa la seconda ultima colonna / campo in awk


164

Voglio stampare la seconda ultima colonna o campo in awk. Il numero di campi è variabile. So che dovrei essere in grado di utilizzare $NFma non sono sicuro di come possa essere utilizzato.

E questo non sembra funzionare:

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

10
NFè l'ultimo indice del campo, $NFè il valore dell'ultimo campo
glenn jackman,

questo ha senso ora. ecco perché il dollaro fuori dalla parentesi funziona suppongo
Brian G,

Risposte:


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

Dovrebbe funzionare


2
Questo non funziona per me. Ottengo "title: 5: comando non trovato: NF-1" in awk 3.1.8 sotto Ubuntu.
Gurgeh,

3
Eviterei il decremento pre / post per assicurarmi di non modificare il valore di $ NF
Gregory Patmore,

Questo si interrompe se si tenta di ottenere il terzo ultimo campo comeawk -F '.' '{print $(NF-2)}'
gies0r

3
@Gurgeh: questo accade perché $(..)invoca un comando in una sottoshell a seconda della shell che stai usando. È possibile aggirare questo utilizzando $ (NF-1)invece di $(NF-1).
mercoledì

21

Piccola aggiunta alla risposta accettata da Chris Kannon: stampa solo se in realtà c'è una seconda ultima colonna.

(
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

È più semplice:

 awk '{print $--NF}' 

Il motivo per cui l'originale $NF--non ha funzionato è perché l'espressione viene valutata prima del decremento, mentre il mio decremento del prefisso viene eseguito prima della valutazione.


Come mnemonico, questo comportamento è lo stesso di C / Java ecc. int x = ++i int x = i++, Prefisso significa prima l'incremento; postfix significa incremento in seguito (prima assegnazione).
Weekend


4

Non eri lontano dal risultato! Questo lo fa:

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

Ciò riduce il numero di campi in uno, in modo che $NFcontenga il penultimo penultimo.

Test

Generiamo alcuni numeri e stampali su gruppi di 5:

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

Stampiamo il penultimo su ogni riga:

$ seq 12 | xargs -n5 | awk '{NF--; print $NF}'
4
9
11

3

Soluzione Perl simile alla soluzione awk di Chris Kannon:

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

Vengono utilizzate queste opzioni della riga di comando:

  • n avvolgere ogni riga del file di input, non stampare automaticamente ogni riga

  • l rimuove le nuove righe prima dell'elaborazione e le aggiunge nuovamente in seguito

  • amodalità autosplit - divide le linee di input @Fnell'array. L'impostazione predefinita è la divisione in spazi bianchi

  • e eseguire il codice perl

La @Fmatrice autosplit inizia all'indice [0] mentre i campi awk iniziano con $ 1.
$#Fè il numero di elementi in@F


1
oppure usa l'indicizzazione negativa già fornita da perl ...$F[-2]
Sundeep,

2

Hai provato a iniziare da destra a sinistra usando il comando rev? In questo caso devi solo stampare la seconda colonna:

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

1

Prima decrementa il valore e poi lo stampa -

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

O

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

0

Se hai molte colonne e vuoi stampare tutte ma non le tre colonne nell'ultima, allora questo potrebbe aiutare

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.