Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 10/02/2016, à 20:09

manon123

[Résolu] Aide sur un Script de tri

Bonsoir,

J'ai suivi le cours sur OpenClassRoom : "Prenez le contrôle à l'aide de linux".
À 50 piges, j'essaie de comprendre le maximum de choses, mais c'est pas facile.
À la fin du cours un exercice est proposé :

Je vais vous demander de créer un script Bash qui fournit des statistiques sur l'utilisation des lettres dans une langue. Pour cela, vous allez devoir vous baser sur un fichier de dictionnaire contenant tous les mots de la langue française que vous pouvez télécharger ci-dessous :

exemple : 
ABAISSA
ABAISSABLE
ABAISSABLES
ABAISSAI
ABAISSAIENT
[...] ==> Z

A partir de ce fichier (dico.txt) vous devez extraire le nombre de mots utilisant chaque lettre de l'alphabet de A à Z. Le script que vous allez créer (langstat.sh) prendra en paramètre le nom du fichier dictionnaire à analyser :
./langstat.sh dico.txt
Le résultat affiché dans la console devrait ressembler à ceci, de la lettre la plus utilisée à la moins utilisée:
  278814 - E
  229938 - A
  219131 - I
  210391 - R
  207889 - S
  179165 - N
  176030 - T
  158282 - O
  [...] ==> Z
Cela signifie que la lettre E apparaît dans 278814 mots du dictionnaire, la lettre A dans 229938 mots, etc.

Voici ce que j'ai fait, en recherchant sur le web et en tâtonnant beaucoup :

#!/bin/bash
egrep [aA] dico.txt > lettre_a
A=`wc -l lettre_a | awk -F ' ' ' {print $1} ' `
echo "$A - A"
egrep [bB] dico.txt > lettre_b
B=`wc -l lettre_b | awk -F ' ' ' {print $1} ' `
echo "$B - B"
egrep [cC] dico.txt > lettre_c
C=`wc -l lettre_c | awk -F ' ' ' {print $1} ' `
echo "$C - C"
egrep [dD] dico.txt > lettre_d
D=`wc -l lettre_d | awk -F ' ' ' {print $1} ' `
echo "$D - D"
egrep [eE] dico.txt > lettre_e
E=`wc -l lettre_e | awk -F ' ' ' {print $1} ' `
echo "$E - E"
egrep [fF] dico.txt > lettre_f
F=`wc -l lettre_f | awk -F ' ' ' {print $1} ' `
echo "$F - F"
egrep [gG] dico.txt > lettre_g
G=`wc -l lettre_g | awk -F ' ' ' {print $1} ' `
echo "$G - G"
egrep [hH] dico.txt > lettre_h
H=`wc -l lettre_h | awk -F ' ' ' {print $1} ' `
echo "$H - H"
egrep [iI] dico.txt > lettre_i
I=`wc -l lettre_i | awk -F ' ' ' {print $1} ' `
echo "$I - I"
egrep [jJ] dico.txt > lettre_j
J=`wc -l lettre_j | awk -F ' ' ' {print $1} ' `
echo "$J - J"
egrep [kK] dico.txt > lettre_k
K=`wc -l lettre_k | awk -F ' ' ' {print $1} ' `
echo "$K - K"
egrep [lL] dico.txt > lettre_l
L=`wc -l lettre_l | awk -F ' ' ' {print $1} ' `
echo "$L - L"
egrep [mM] dico.txt > lettre_m
M=`wc -l lettre_m | awk -F ' ' ' {print $1} ' `
echo "$M - M"
egrep [nN] dico.txt > lettre_n
N=`wc -l lettre_n | awk -F ' ' ' {print $1} ' `
echo "$N - N"
egrep [oO] dico.txt > lettre_o
O=`wc -l lettre_o | awk -F ' ' ' {print $1} ' `
echo "$O - O"
egrep [pP] dico.txt > lettre_p
P=`wc -l lettre_p | awk -F ' ' ' {print $1} ' `
echo "$P - P"
egrep [qQ] dico.txt > lettre_q
Q=`wc -l lettre_q | awk -F ' ' ' {print $1} ' `
echo "$Q - Q"
egrep [rR] dico.txt > lettre_r
R=`wc -l lettre_r | awk -F ' ' ' {print $1} ' `
echo "$R - R"
egrep [sS] dico.txt > lettre_s
S=`wc -l lettre_s | awk -F ' ' ' {print $1} ' `
echo "$S - S"
egrep [tT] dico.txt > lettre_t
T=`wc -l lettre_t | awk -F ' ' ' {print $1} ' `
echo "$T - T"
egrep [uU] dico.txt > lettre_u
U=`wc -l lettre_u | awk -F ' ' ' {print $1} ' `
echo "$U - U"
egrep [vV] dico.txt > lettre_v
V=`wc -l lettre_v | awk -F ' ' ' {print $1} ' `
echo "$V - V"
egrep [wW] dico.txt > lettre_w
W=`wc -l lettre_w | awk -F ' ' ' {print $1} ' `
echo "$W - W"
egrep [xX] dico.txt > lettre_x
X=`wc -l lettre_x | awk -F ' ' ' {print $1} ' `
echo "$X - X"
egrep [yY] dico.txt > lettre_y
Y=`wc -l lettre_y | awk -F ' ' ' {print $1} ' `
echo "$Y - Y"
egrep [zZ] dico.txt > lettre_z
Z=`wc -l lettre_z | awk -F ' ' ' {print $1} ' `
echo "$Z - Z"
sort -f $*

Le fichier Dico : Téléchargement Dico

Je me doute qu'il y a plus facile.
Premier problème, lorsque je l'exécute, ça me crée un fichier pour chaque lettre, c'est normal?
Deuxième problème, je suis allé voir man sort et il dit d'employer l'option -f pour trier numériquement le fichier. Ici, j'ai repris toutes les variables avec * et bien sûr ça fonctionne pas.
Une explication serait la bienvenue. Je vois pas comment faire ça avec une fonction ou des conditions (attention, c'est mon premier script :-) ).

Je suppose qu'il me crée un fichier par lettre à cause de la direction :

> lettre_xxx

Merci beaucoup.

Dernière modification par manon123 (Le 10/02/2016, à 23:41)


Distro: Manjaro 20.1-2

Hors ligne

#2 Le 10/02/2016, à 21:12

pingouinux

Re : [Résolu] Aide sur un Script de tri

Bonsoir,

Premier problème, lorsque je l'exécute, ça me crée un fichier pour chaque lettre, c'est normal?

Tel que tu l'as fait, oui.

Deuxième problème, je suis allé voir man sort et il dit d'employer l'option -f pour trier numériquement le fichier.

Pour trier numériquement, c'est sort -n (sort -f fait un tri sans tenir compte de la casse).

Je regarde ton script pour voir comment le simplifier.

Hors ligne

#3 Le 10/02/2016, à 21:27

Watael

Re : [Résolu] Aide sur un Script de tri

la première simplification serait de factoriser les commandes dans une boucle itérant sur les lettres de l'alphabet.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#4 Le 10/02/2016, à 21:31

pingouinux

Re : [Résolu] Aide sur un Script de tri

Voilà !
Il y a une boucle sur les lettres. L'option -i de grep ignore la casse, et l'option -c donne le compte des lignes qui contiennent l'expression. Le tri s'effectue sur la sortie standard de la boucle.

#!/bin/bash

dico=$1
for lettre in {A..Z}
do
   printf "%s - %s\n" $(grep -ic $lettre "$dico")  $lettre
done | sort -rn

On doit pouvoir améliorer, car le fichier est ici lu entièrement pour chaque lettre.

Hors ligne

#5 Le 10/02/2016, à 21:52

pingouinux

Re : [Résolu] Aide sur un Script de tri

#!/bin/bash

dico=$1
declare -A resul

while read mot
do
   for lettre in {A..Z}
   do
      grep -q $lettre <<<"$mot" && ((resul[$lettre]++))
   done 
done <"$dico"

for lettre in "${!resul[@]}"
do
   echo ${resul[$lettre]} "-" $lettre 
done | sort -rn

Le dico n'est lu qu'une seule fois, ligne par ligne. En sortie, on n'a plus que la liste des lettres apparaissant au moins une fois.

Dernière modification par pingouinux (Le 10/02/2016, à 22:51)

Hors ligne

#6 Le 10/02/2016, à 22:32

manon123

Re : [Résolu] Aide sur un Script de tri

Merci pingouinux,

Mais quand je lance le script n°2 après lui avoir donné le droit d'exécution, il ne se passe rien dans la console.

bruno@bruno-All-Series:~$ cd Bureau
bruno@bruno-All-Series:~/Bureau$ ./langstat2.sh dico.txt 

Le curseur clignote et c'est tout. 

Par contre le premier fonctionne.

Tu peux m'expliquer

"%s - %s\n" $(grep -ic $lettre "$dico")  $lettre ?

Merci


Distro: Manjaro 20.1-2

Hors ligne

#7 Le 10/02/2016, à 23:02

pingouinux

Re : [Résolu] Aide sur un Script de tri

Je pensais à tort que le script en #5 aurait été plus rapide que celui en #4, mais il prend un temps fou sur ton gros fichier dico.txt. Le tien, en #1, est le plus rapide, mais il n'est pas très joli…

printf "%s - %s\n" $(grep -ic $lettre "$dico")  $lettre

C'est une impression avec format :
"%s - %s\n" : format, qui va être suivi de 2 chaînes de caractères (ici un nombre et une lettre)
$(grep -ic $lettre "$dico") : nombre d'occurrences de la lettre de lignes contenant la lettre dans le dico
$lettre : la lettre

On aurait pu faire :

echo $(grep -ic $lettre "$dico") "-" $lettre

Dernière modification par pingouinux (Le 16/03/2016, à 13:11)

Hors ligne

#8 Le 10/02/2016, à 23:42

manon123

Re : [Résolu] Aide sur un Script de tri

Merci beaucoup pingouinux,

Je mets le sujet en résolu big_smile


Distro: Manjaro 20.1-2

Hors ligne

#9 Le 16/03/2016, à 06:51

pingouinux

Re : [Résolu] Aide sur un Script de tri

Réponse au message personnel de mathieudex
Bonjour,
Il est préférable de poser ta question ici (ou dans une nouvelle discussion). Elle pourra ainsi profiter à la communauté, et tu multiplieras tes chances d'obtenir une réponse pertinente.

Ceci dit, je n'ai pas compris ce que tu voulais. Montre un exemple (petit fichier de départ et résultat souhaité).

Hors ligne

#10 Le 16/03/2016, à 11:36

mathieudex

Re : [Résolu] Aide sur un Script de tri

pingouinux a écrit :

Réponse au message personnel de mathieudex
Bonjour,
Il est préférable de poser ta question ici (ou dans une nouvelle discussion). Elle pourra ainsi profiter à la communauté, et tu multiplieras tes chances d'obtenir une réponse pertinente.

Ceci dit, je n'ai pas compris ce que tu voulais. Montre un exemple (petit fichier de départ et résultat souhaité).

Bonjour,

J'ai créé une nouvelle discussion en expliquant un peu mieux ce que je souhaitais faire
Merci d'avance

Hors ligne