Comment trier la sortie de mes variables avec sort dans mon script bash ?


#21

je fais un retour du script les mec’s ,
il fonctionne jusqu’a grep ,.Il me renvoi bien tout les caractère de A a Z mais la commande sort ne s’effectue pas , je l’ai mis a la fin de done comme montrer dans l’exemple , puis avant , puis dans les parenthèse , mais je n’ai pas réussi a le "chainer " a la cmd grep :confused:

Je devait aussi mettre dicotoutcourt en paramettre $1 .
J’ai tenté plusieurs scripts avec if ( pour la condition "si le paramètre est vide ou différent de dicotoutcourt , alors répété l’action jusqu’a ce que le parametre soit “dicotoutcourt” j’ai essayé avec while mais le soucis c’est que mon script s’enchaîne sans s’arrêté en disant :
taper le bon parametre !
taper le bon parametre !
taper le bon parametre !
lol
voilà voilà , donc finalement j’aurais du le tester dès le début pour vous expliqué directement tout ça lol ^^


#22

Comme vous n’avez pas expliqué comment est organisé le fichier Dicotoutcourt voici un script fonctionnel qui montre comment résoudre votre problème :
écrire une fonction nmots() qui émet le contenu du dictionnaire sous une forme normalisée c’est-à-dire avec un mot par ligne
la partie principale du programme

for l in a b c d e f g h i j k l m n o p q r s t u v w x y z
do 
   t=$(mots | fgrep -c -i $l)
   echo $l "=" $t
done | sort -nr -k3

Le script

#! /bin/bash

contenu() {
cat << EOF | sed -e '/^#/d'
# deutsch
eins zwei drei
# english
one two  three
# fr
un deux trois
EOF
}

DICO=$(contenu)
echo $DICO

# commande qui émet les mots sous une forme normalisée : un mot par ligne
mots()
 { echo $DICO | tr ' ' '\n' | sed -e '/^$/d'
 }

# for l in {a .. z}
for l in a b c d e f g h i j k l m n o p q r s t u v w x y z
do 
   t=$(mots | fgrep -c -i $l)
   echo $l "=" $t
done | sort -nr -k3

Il me semble qu’avec cet exemple vous comprendrez les tenants et aboutissants de la syntaxe

$(commande arg1 ... )

Vous remarquerez aussi que j’ai abandonné la syntaxe {A…Z} car avec ces histoires de nombres de points, de présence éventuelle d’espaces ou de ‘$’ ou autre, je ne suis pas arrivé à faire fonctionner l’instruction for

Cordialement,
Regards,
Mit freundlichen Grüßen,
مع تحياتي الخالصة


F. Petitjean
Ingénieur civil du Génie Maritime.

« On ne perd pas son temps en aiguisant ses outils. »
Proverbe français

« Moi, lorsque je n’ai rien à dire, je veux qu’on le sache. » (R. Devos)


#23

Salut Littlejohn75 . Je te remercie pour cette magnifique illustration ;

J’ai malheureusement pour le moment un autre problème trés contraignant à régler après une fausse manip qui m’a tout déplacer ( ou peut être supprimer mais rien dans la corbeille .)
https://www.debian-fr.org/t/jai-tout-supprimer-ou-presque/

Mais à première vue , nouveauté pour moi avec les commandes sed et tr . ce n’est pas la première fois que je vois sed , qui m’a l’air d’etre un puissant programme mais aussi plus compliqué avec toutes ces expressions régulières .
si je me rappel de ce que j’ai lu les expression de sed et quelque autres programmes sont propre a eux même nan ? “[” aurait une autre signification dans un autre programme par exemple non ?

Mile merci pour tout ce savoir littlejhon . à toute , une fois mon soucis réglé ^^.

je reviens vite donné pour retour mais apparemment

.Il faut payer pour apprendre disait mon grand-père ^^
ps : le fichier( que j’ai fait disparaitre en même temps que le reste lol )est un vrai dictionnaire avec seulement les mots sans la definition ecris à chaque ligne :
mot1
mot2


#24

Ce genre de structure, je ne l’appellerais pas dictionnaire mais tout simplement liste (triée) de mots :joy:
Dans ce cas le canevas que j’ai posté s’adapte avec

mots() {
  cat /chemin/vers/fichier
}

sed the stream editor, est je vous l’accorde quelque peu difficile d’accès pour un débutant. Par contre tr est extrêmement simple à comprendre

echo tapadaca | tr 'a' 'u'
tupuducu

on ne peut même pas appliquer la transformation à un fichier, seulement à un flux (stdin stdout)
Dans le

man sed
....
SEE ALSO
       awk(1), ed(1), grep(1), tr(1),  perlre(1),  sed.info,

La référence est à ed Ed is the standard text editor.
On peut regretter que les éditeurs vi (et vim) ne soient pas cités (ne font pas partie du projet GNU ?).
Avec ces éditeurs un peu moins frustres que ed on passe en mode ed en tapant : (depuis le mode commande).
Exemple d’utilisation de tr et cut

cat /etc/passwd | tr ':' '\t' | cut -f 3,5,6 | less

Cordialement,
Regards,
Mit freundlichen Grüßen,
مع تحياتي الخالصة


F. Petitjean
Ingénieur civil du Génie Maritime.

« On ne perd pas son temps en aiguisant ses outils. »
Proverbe français

« Moi, lorsque je n’ai rien à dire, je veux qu’on le sache. » (R. Devos)


#25

C’est quoi ce binz ?!

sed peut parfaitement travailler sur un fichier.

Si tu as un fichier toto.txt contenant la chaîne de caractères “tapadaca”, un “sed -i s/a/u/g toto.txt” va te remplacer tous les “a” par des “u” dans le fichier toto.txt.

Et tu peux faire bien plus élaboré dans un fichier : aller à une ligne donnée (soit par son numéro, soit suite à une recherche de motif), supprimer des lignes, en ajouter…

Amicalement.

Jean-Marie


#26

on se calme.
il fallait lire

et j’ai simplement oublier de mettre un bon nombre de lignes vides pour séparer le paragraphe suivant qui parlait de sed.
J’ose espérer que vous avez lu avec attention le lien donné pour ed :smiley:

Cordialement,
Regards,
Mit freundlichen Grüßen,
مع تحياتي الخالصة


F. Petitjean
Ingénieur civil du Génie Maritime.

R: Parce que ça renverse bêtement l’ordre naturel de lecture !
Q: Mais pourquoi citer en fin de message est-il si effroyable ?
R: Répondre au dessus de la citation
Q: Quelle est la chose la plus désagréable dans un message ?


#27

J’ai dû commencé à utiliser ed en 1981 ; de mémoire.

Si j’ai lu comme ça, c’est que ce n’était pas clair.

En ce qui me concerne, ce n’est pas grave, je connais ed et tr. Mais pour ceux qui connaissent moins…

Amicalement.

Jean-Marie


#28

Pas sûr que ça réponde entièrement à la demande de départ:

La proposition de @diesel renvoie toutes les occurences de la lettre au sein du fichier (si plusieurs A dans une même ligne, ils sont tous comptés)
Ça déborde un peu puisque ça va compter 2 “mots utilisant A” pour 1 “mot utilisant 2 A”.

La proposition de @Sputnik93 renvoie le nombre de lignes où apparaît la lettre visée.
S’il n’y a qu’un seul mot par ligne du fichier, ça va. Mais si le fichier contient plusieurs mots par ligne, ça ne comptera pas 2 mots sur une même ligne.
Sans doute un truc à affiner avec du awk ou du sed pour faire la division de lignes en mots pour couvrir le cas de plusieurs mots par ligne (un peu dans le goût de ce que propose @littlejohn75 ) .
(Pas le temps de faire ça maintenant, mais je vais essayer de creuser quand je pourrai)


#29

Bonjour Choops,

Tu as raison par rapport au titre.

Par contre, par rapport à ce que Morpheus avait commencé à coder, ma proposition compte bien la même chose.

Amicalement.

Jean-Marie


#30

Oui, en effet, tu repars bien dans le sens du code de base proposé par Morpheus.
Je constatais juste que le comptage obtenu ne correspondait pas forcément à l’énoncé du problème à traiter.

Petite illustration en un script qui permet de comparer les retours des méthodes proposées:

!/usr/bin/env bash

path=$(dirname "$(realpath "$0")")
file=testfile

cat << EOF > "${path}/${file}"
pif
paf
pouf
tete
linked-word
2 words
or more
EOF

if [ -z "$1" ] || [ "$1" != "${file}" ]; then
    echo "[ERROR] One parameter is expected." && exit

else
    echo "diesel's method: count each letter occurrence"
    for letter in {A..Z} ; do
        echo "$letter: $(grep -io ["${letter}"] "${path}/${file}" | wc -l)"
    done | sort -nr -k2

    echo "Sputnik93's method: count lines containing at least once the letter"
    for letter in {A..Z} ; do
        echo "$letter: $(grep -ic ["${letter}"] "${path}/${file}")"
    done | sort -nr -k2

    echo "My test: cut lines on spaces to obtain a workfile with one word per line, then apply Sputnik93's method to count in workfile"
    workfile=/tmp/"${file}"
    sed -e 's/ /\n/g' -e '/^$/d' "${path}/${file}" > "${workfile}"
    for letter in {A..Z} ; do
        echo "${letter}: $(grep -ic ["${letter}"] ${workfile}"
    done | sort -nr -k2

fi

Je ne pense pas être trop loin avec la 3ème méthode ‘My test’ de ce script. (Il y a sans doute des cas de comptage spécifique que je n’ai pas pris le temps de cerner, mais ça doit déjà relativement bien compter)