137 votes

Afficher tout sauf le premier champ avec awk

J'ai un fichier qui ressemble à ceci :

AE  Émirats arabes unis
AG  Antigua-et-Barbuda
AN  Antilles néerlandaises
AS  Samoa américaines
BA  Bosnie-Herzégovine
BF  Burkina Faso
BN  Brunéi Darussalam

Et je voudrais inverser l'ordre, en affichant d'abord tout sauf $1, puis $1 :

Émirats arabes unis AE

Comment puis-je réaliser l'astuce "tout sauf le champ 1" ?

2 votes

Bonjour @cfisher, cela peut être fait sans boucle et sans espace supplémentaire.

1 votes

La formulation de la question est un peu trompeuse. Mon avis: "Comment déplacer le premier champ à la dernière position dans awk"

129voto

7winkie Points 371

$1="" laisse un espace comme l'a mentionné Ben Jackson, utilisez donc une boucle for :

awk '{for (i=2; i<=NF; i++) print $i}' filename

Donc si votre chaîne était "un deux trois", la sortie sera :

deux
trois

Si vous voulez le résultat sur une seule ligne, vous pouvez faire comme suit :

awk '{for (i=2; i

`

Cela vous donnera : "deux trois"

`

4 votes

Et un espace supplémentaire après

2 votes

Mieux vaut utiliser : awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}' qui : imprime les champs 2 à NF, ajoute le séparateur de champ de sortie si nécessaire (c'est-à-dire, sauf avant $2). Le dernier print ajoute une nouvelle ligne finale pour terminer l'impression de la ligne actuelle. Celui-ci fonctionnera si vous changez FS/OFS (c'est-à-dire, ce ne sera pas toujours "espace")

0 votes

Le deuxième a vraiment bien fonctionné pour moi. Le premier, pas tellement. Pas vraiment sûr pourquoi. Cela a découpé tout le texte.

112voto

Ben Jackson Points 28358

L'affectation de $1 fonctionne mais elle laissera un espace en tête: awk '{first = $1; $1 = ""; print $0, first; }'

Vous pouvez également trouver le nombre de colonnes dans NF et l'utiliser dans une boucle.


De Thyag : Pour éliminer l'espace en tête, ajoutez sed à la fin de la commande :

awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'

2 votes

Pour les totalement paresseux; voici le code de klashxx.

2 votes

Super. Se débarrasser de l'espace initial avec sed : awk {'premier = $1; $1=""; imprimer $0'}|sed 's/^ //g'

0 votes

L'espace est facilement supprimé avec VIM en appuyant sur 'Ctrl+V Gd' en mode normal

86voto

zeleniy Points 393

Utilisez la commande cut avec -f 2- (POSIX) ou --complement (non POSIX) :

$ echo a b c | cut -f 2- -d ' '
b c
$ echo a b c | cut -f 1 -d ' '
a
$ echo a b c | cut -f 1,2 -d ' '
a b
$ echo a b c | cut -f 1 -d ' ' --complément
b c

3 votes

En ne répondant pas à la question spécifique à awk, j'ai trouvé cela très utile car awk supprimait les espaces dupliqués, et cut non.

21 votes

echo a b c | cut -d' ' -f 2- est une alternative

3 votes

Belle - La solution de @Luis fonctionne sur Mac, qui ne prend pas en charge --complement

26voto

klashxx Points 1695

Peut-être la façon la plus concise:

$ awk '{$(NF+1)=$1;$1=""}sub(FS,"")' fichier
Emirats Arabes Unis AE
Antigua-et-Barbuda AG
Antilles néerlandaises AN
Samoa américaines AS
Bosnie-Herzégovine BA
Burkina Faso BF
Brunei Darussalam BN

Explication:

$(NF+1)=$1: Générateur d'un "nouveau" dernier champ.

$1="": Définit le premier champ original à null

sub(FS,""): Après les deux premières actions {$(NF+1)=$1;$1=""} se débarrassent du séparateur de champ en utilisant sub. L'impression finale est implicite.

0 votes

Peut-être que j'ai raté quelque chose, mais cela n'a pas fonctionné pour moi sur gawk 5.1 -- cela a simplement déplacé le premier champ à la fin de l'impression au lieu de l'ignorer.

1 votes

C'est parce que la formulation de la question est trompeuse @SorenBjornstad. Devrait être : "Comment déplacer le premier champ en dernière position"

1 votes

Il s'agit d'une belle solution au problème d'avoir un espace initial ou final lorsque vous utilisez le $1="" (ou $NF="", ou tout ce que vous faites). +1 de ma part.

10voto

dubiousjim Points 2259
awk '{ saved = $1; $1 = ""; print substr($0, 2), saved }'

En mettant le premier champ à "", il reste une seule copie de OFS au début de $0. En supposant que OFS est uniquement un seul caractère (par défaut, c'est un seul espace), nous pouvons le supprimer avec substr($0, 2). Ensuite, nous ajoutons la copie sauvegardée de $1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X