2010-11-29 5 views

Répondre

158

Vous pouvez utiliser la variable NF qui est réglée sur le nombre total de champs dans l'enregistrement d'entrée:

awk '{print $(NF-1),"\t",$NF}' file 

cela suppose que vous avez au moins 2 champs.

+1

Vous avez besoin d'une virgule - depuis nous sommes en train d'être difficiles aujourd'hui: l'espace concatène les champs, la virgule sépare les champs dans une instruction print. Cela va fusionner les deux champs –

+15

Maintenant vous imprimez "field-OFS-tab-OFS-field".Il devrait être 'awk '{print $ (NF-1)" \ t "$ NF}' fichier 'ou' awk' {imprimer $ (NF-1), $ NF} 'fichier' ou 'awk' BEGIN {OFS = "\ t"} {print $ (NF-1), $ NF} 'fichier'. –

10
awk '{print $NF-1, $NF}' inputfile 

Remarque: cela ne fonctionne que s'il existe au moins deux colonnes. Sur les enregistrements avec une colonne, vous obtiendrez une fausse "-1 column1"

+7

'$ NF-1' ne fonctionnera pas. – codaddict

+2

Essayez et voyez. Cela fonctionne Solaris 9 awk & nawk. L'alternative est $ (NF-1) –

+1

Ici vous allez: http://www.ideone.com/FQCuF – codaddict

1

utilisant gawk présente le problème:

gawk '{ print $NF-1, $NF}' filename 
1 2 
2 3 
-1 one 
-1 three 
# cat filename 
1 2 
2 3 
one 
one two three 

Je viens de mettre gawk sur Solaris 10 M4000: Ainsi, gawk est le cuplrit sur la question par rapport à $ (NF-1) NF-1 $. Question suivante, que dit POSIX? par:

http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html 

Il n'y a pas de direction d'une façon ou l'autre. Pas bon. gawk implique une soustraction, d'autres awks impliquent un numéro de champ ou une soustraction. hmm.

+1

Les deux premières lignes de votre exemple de fichier d'entrée ne sont pas utiles car elles produisent la même sortie avec le comportement _either_. Pouvez-vous s'il vous plaît reconfirmer que Solaris awk ne se comporte en effet PAS comme gawk dans ce cas? – mklement0

+0

En ce qui concerne votre lien vers la spécification awk: L'argument anecdotique pour utiliser '$ (NF-1)' est que les deux exemples de calcul de l'index de champ dans la spécification utilisent tous deux cette forme: '$ (NF-1)' '$ (NF + 2)'. Ensuite, il y a la section "Expressions dans awk", qui liste '$ expr' comme ayant [beaucoup] plus de priorité que 'expr-expr'. Comme 'NF' est une expression elle-même,' $ NF-1' devrait évaluer '($ NF) -1'. Même si, après tout, il y a effectivement des implémentations awk là-bas qui évaluent '$ NF-1' comme' $ (NF-1) ', la leçon apprise ici est que l'utilisation de' $ (NF-1) 'est la sécurité et choix portable. – mklement0

7

@jim mcnamara: essayez d'utiliser des parenthèses pour environ NF, i. e. $(NF-1) et $(NF) au lieu de $NF-1 et $NF (fonctionne sur Mac OS X 10.6.8 pour FreeBSD awk et gawk).

echo ' 
1 2 
2 3 
one 
one two three 
' | gawk '{if (NF >= 2) print $(NF-1), $(NF);}' 

# output: 
# 1 2 
# 2 3 
# two three 
+0

Nous avions déjà considéré() plus tôt. Je pensais que nous étions en train de discuter d'où venait le vieux comportement d'awk. –

+0

+1 pour une réponse avec «$ (NF-1)» explicite - qui est à tout le moins plus portable que «$ NF-1»; c'est nettement moins ambigu. '$ (NF)' est surfait, cependant - seulement '$ NF' fera l'affaire. La protection contre les lignes de moins de 2 colonnes vaut également la peine, car avec les lignes à une colonne, vous obtiendrez la première valeur de la colonne * deux fois *, et avec les lignes zéro-colonne, la commande awk échouera une tentative d'accès à un champ avec index -1. – mklement0

Questions connexes