Filtrage de chaîne de caractères en Shell

Voici un snippet qui permet de filtrer et de transformer une chaîne de caractères afin de pouvoir l'utiliser dans une URL ou pour un nom de fichier ou de répertoire.

Il a été testé avant tout sous Bash mais ne devrait pas poser de problèmes particulier pour son portage sous d'autres Shell excepté pour l'option -n de la commande echo.

Intérêt

Ce snippet permet de s'assurer qu'une chaîne de caractères pourra être utilisée dans la construction d'une URL ou d'un nom de fichier ou de répertoire.

Son intérêt principal réside dans le niveau de sécurité qu'elle autorise vis-à-vis de données fournies par les utilisateurs.

Il permet aussi de créer des URL propres sans accents, majuscules, espaces ou caractères spéciaux (/, &, + etc.)

Pré-requis

La commande iconv doit être installée et accessible au script.

Hormis cette commande, seule la commande tr est utilisée mais celle-ci est un standard sous Unix.

Fonctionnement

Le snippet consiste en une succession de tubes/pipes.

La chaîne générée ne sera composée que de lettres minuscules non accentuées et de tirets '-'.

printf '%s' "$oldname"

La commande printf est à utiliser de préférence à la commande echo car la première permet l’utilisation de n’importe quelle chaîne contrairement à la seconde. De plus, elle ne nécessite pas d’option particulière pour empêcher la génération automatique d’un retour à la ligne.

iconv -f utf-8 -t ascii//TRANSLIT

La commande iconv convertit une chaîne encodée UTF-8 (-f utf-8) en une chaîne encodée Ascii (-t ascii//TRANSLIT).

L'option //TRANSLIST demande à iconv de faire de la translittération : - chaque caractère est transformé en son équivalent le plus proche. Cela permet, par exemple, d'obtenir la lettre e pour é, è, ê, ë etc. - les ligatures sont également concernées (oe, ae etc.), - le symbole '€' est transformé en 'EUR', - les caractères ne pouvant profiter favorablement de ce traitement sont remplacés par '?'

sed

La commande sed utilise plusieurs expressions rationnelles pour nettoyer la chaîne de caractères générée par iconv. Cette particularité permet de réduire le nombre de tubes utilisés contrairement à ce que des commandes tr aurait obligé.

Dans le détail, ces expressions sont :

Code source

newname=$(printf '%s' "$oldname" | \
    iconv -f utf-8 -t ascii//TRANSLIT | \
    sed -r -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \
           -e 's/[^a-z]+/-/g' \
           -e 's/-+/-/g' \
           -e 's/^-//' \
           -e 's/-$//' \
)