Imprimir a segunda última coluna / campo no awk


164

Quero imprimir a segunda última coluna ou campo no awk. O número de campos é variável. Eu sei que devo poder usar, $NFmas não tenho certeza de como ele pode ser usado.

E isso não parece funcionar:

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

10
NFé o último índice de campo, $NFé o valor do último campo
glenn jackman

isso faz sentido agora. é por isso que o dólar fora do parêntese trabalha suponho
Brian G

Respostas:


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

Deveria trabalhar


2
Isso não funciona para mim. Eu recebo "title: 5: comando não encontrado: NF-1" no awk 3.1.8 no Ubuntu.
Gurgeh

3
Gostaria de evitar a pré / pós decrement para se certificar de que você não alterar o valor de US $ NF
Gregory Patmore

Isso quebra se você tentar obter o terceiro último campo comoawk -F '.' '{print $(NF-2)}'
gies0r

3
@ Gurgeh: Isso acontece porque $(..)chama um comando em um subshell, dependendo de qual shell você está usando. Você pode contornar isso usando em $ (NF-1)vez de $(NF-1).
wting 14/10/18

21

Pequeno acréscimo à resposta aceita por Chris Kannon: imprima apenas se houver realmente uma segunda última coluna.

(
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

É mais simples:

 awk '{print $--NF}' 

A razão pela qual o original $NF--não funcionou é porque a expressão é avaliada antes do decremento, enquanto o meu decremento de prefixo é realizado antes da avaliação.


Como mnemônico, esse comportamento é o mesmo que C / Java etc. int x = ++i int x = i++, prefixo significa incremento primeiro; postfix significa incremento mais tarde (atribuição primeiro).
Fim de semana


4

Você não estava longe do resultado! Faz isso:

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

Isso diminui o número de campos em um, para que $NFcontenha o penúltimo ex.

Teste

Vamos gerar alguns números e imprimi-los em grupos de 5:

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

Vamos imprimir o penúltimo em cada linha:

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

3

Solução Perl semelhante à solução awk de Chris Kannon:

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

Essas opções de linha de comando são usadas:

  • n faça um loop em todas as linhas do arquivo de entrada, não imprima automaticamente todas as linhas

  • l remove as novas linhas antes do processamento e as adiciona novamente depois

  • amodo de divisão automática - divida as linhas de entrada na @Fmatriz. O padrão é dividir em espaço em branco

  • e executar o código perl

A @Fmatriz de divisão automática inicia no índice [0] enquanto os campos awk começam com $ 1.
$#Fé o número de elementos em@F


1
ou usar a indexação negativa já fornecido pelo perl ...$F[-2]
Sundeep

2

Você tentou iniciar da direita para a esquerda usando o comando rev? Nesse caso, você só precisa imprimir a segunda coluna:

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

1

Primeiro diminui o valor e depois imprime -

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

OU

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

0

Se você tiver muitas colunas e quiser imprimir todos, exceto os três, no último, isso pode ajudar

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.