#!/bin/bash
# wstrings.sh: "word-strings" (commande "strings" améliorée)
#
#  Ce script filtre la sortie de "strings" en la comparant avec une liste de
#+ mots communs.
#  Ceci élimine efficacement le bruit et n'affiche que les mots reconnus.

# =================================================================
#               Vérification standard des arguments du script
ARGS=1
E_MAUVAISARGS=65
E_AUCUNFICHIER=66

if [ $# -ne $ARGS ]
then
  echo "Usage: `basename $0` nomfichier"
  exit $E_MAUVAISARGS
fi

if [ ! -f "$1" ]                        # Vérifie si le fichier existe.
then
    echo "Le fichier \"$1\" n'existe pas."
    exit $E_AUCUNFICHIER
fi
# =================================================================


LONGUEUR_CHAINE_MINIMUM=3                 #  Longueur minimum d'une chaîne.
FICHIER_MOTS=/usr/share/dict/linux.words  #  Dictionnaire.
                                          #  Vous pouvez spécifier un autre
					  #+ fichier de mots, à condition que
					  #+ son format soit d'un mot par ligne.


listemots=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
tr -cs '[:alpha:]' Z | tr -s '\173-\377' Z | tr Z ' '`

# Traduit la sortie de la commande 'strings' avec de multiples passes de 'tr'.
#  "tr A-Z a-z" réalise une conversion en minuscule.
#  "tr '[:space:]'" change les espaces blancs par des Z.
#  "tr -cs '[:alpha:]' Z" change les caractères non alphabétiques en Z.
#+ et ne conserve qu'un seul Z pour les Z successifs.
#  "tr -s '\173-\377' Z" convertit tous les caractères après 'z' en Z
#+ et ne conserve qu'un seul Z pour les Z successifs
#+ ce qui supprime tous les caractères bizarres que la précédente passe aurait
#+ oublié de gérer.
#  Finalement, "tr Z ' '" convertit tous les Z en espaces blancs,
#+ ce qui sera vu comme des mots séparés dans la boucle ci-dessous.

# ***************************************************************************
#  Notez la technique de remplissage de la sortie de 'tr' vers lui-même,
#+ mais avec différents arguments et/ou options à chaque passe.
# ***************************************************************************


for mot in $listemots    # Important :
                         # $listemots ne doit pas être entre guillemets ici.
                         # "$listemots" ne fonctionne pas.
                         # Pourquoi pas ?
do

  longueur_chaine=${#mot}                     # Longueur de la chaîne.
  if [ "$longueur_chaine" -lt "$LONGUEUR_CHAINE_MINIMUM" ]
  then                   # Ne pas tenir compte des petites chaînes.
    continue
  fi

  grep -Fw $mot "$FICHIER_MOTS"       # Correspond seulement aux mots complets.
#       ^^^                           #  Options "chaînes corrigées" et
                                      #+ "mots complets".

done  


exit $?
