Je dois trier tous les mots d'un fichier donné en paramètre dans un script Shell. Voici le one-liner:
tr [:space:] '\n' <$1 | sort -nrk2,2 | uniq -c |sed 's/^ \+//g'
En gros, si j'ai quelque chose comme ça dans mon dossier:
bla bla bla bla hu hu hu
Il va sortir
4 bla
3 hu
Je veux qu'ils soient quelque chose comme
bla 4
hu 3
Vous pouvez remplacer votre commande sed
par une simple commande awk
qui permute l'ordre des champs.
... | awk '{print $2,$1}'
Il y a beaucoup de façons de faire cela. Steeldriver vous a déjà présenté l'approche classique awk
. Voici quelques autres choix:
Utilisez sed
pour capturer deux groupes de caractères autres qu’espaces (\S
), puis alternez-les:
... | sed -E 's/\s*(\S+)\s+(\S+)/\2 \1/'
Utilisez Perl
. Son commutateur -a
le fait fonctionner comme awk
. Il scinde automatiquement chaque ligne d'entrée en blanc et enregistre chaque champ en tant qu'élément du tableau @F
. Par conséquent, le premier champ sera $F[0]
, le second $F[1]
etc .:
... | Perl -lane 'print "$F[1] $F[0]"'
Utilisez Perl pour le tout:
Perl -lane '$k{$_}++ for @F; }{ print "$_ $k{$_}" for keys(%k)' "$1"
Ici, Perl
lit le fichier d'entrée ligne par ligne et applique le script à chaque ligne. $k{$_}++ for @F
enregistre chaque mot (chaque champ de @F
) en tant que clé dans le hachage %k
et incrémente la valeur associée d'un à chaque fois que le mot est vu. Ensuite, une fois que le fichier a été traité (c'est ce que signifie }{
), il imprimera le mot ($_
) et le nombre de fois qu'il a été vu ($k{$_}
) pour chaque clé. stocké dans le hachage.
Utilisez awk
pour le tout:
awk '{for(i=1;i<=NF;i++){a[$i]++}}END{for(i in a){print i,a[i]}}' "$1"
La première boucle for
survole chaque champ et en ajoute un à la valeur associée à ce champ dans le tableau a
. Puis, à la fin du fichier, il boucle sur chaque élément de a
et affiche l'élément (le mot) et la valeur associée (le nombre de fois que le mot a été vu).
Utilisez le shell avec votre pipeline d'origine:
... | while read a b; do echo "$b $a"; done