web-dev-qa-db-fra.com

Dans un script bash, comment nettoyer les entrées utilisateur?

Je cherche la meilleure façon de prendre une entrée simple:

echo -n "Enter a string here: "
read -e STRING

et nettoyez-le en supprimant les caractères non alphanumériques, en minuscules (casse) et en remplaçant les espaces par des traits de soulignement.

L'ordre est-il important? Est-ce que tr est la meilleure/la seule façon de procéder?

43
Devin Reams

Comme le souligne dj_segfault, le Shell peut faire la plupart de cela pour vous. On dirait que vous devrez vous rabattre sur quelque chose d'extérieur pour le boîtier inférieur de la corde, cependant. Pour cela, vous avez de nombreuses options, comme les one-liners Perl ci-dessus, etc., mais je pense que c'est probablement la plus simple.

# first, strip underscores
CLEAN=${STRING//_/}
# next, replace spaces with underscores
CLEAN=${CLEAN// /_}
# now, clean out anything that's not alphanumeric or an underscore
CLEAN=${CLEAN//[^a-zA-Z0-9_]/}
# finally, lowercase with TR
CLEAN=`echo -n $CLEAN | tr A-Z a-z`

L'ordre ici est assez important. Nous voulons nous débarrasser des traits de soulignement, et remplacer les espaces par des traits de soulignement, nous devons donc être sûrs de supprimer les traits de soulignement en premier. En attendant de passer les choses à tr jusqu'à la fin, nous savons que nous n'avons que des caractères alphanumériques et des traits de soulignement, et nous pouvons être sûrs que nous n'avons pas d'espaces, donc nous n'avons pas à nous soucier des caractères spéciaux interprétés par le Shell.

44
Thomee

Bash peut tout faire tout seul, merci beaucoup. Si vous regardez la section de la page de manuel sur Expansion des paramètres, vous verrez que bash a des substitutions intégrées, sous-chaîne, trim, rtrim, etc.

Pour éliminer tous les caractères non alphanumériques, faites

CLEANSTRING=${STRING//[^a-zA-Z0-9]/}

C'est le rasoir d'Occam. Pas besoin de lancer un autre processus.

34
dj_segfault

Rapide et sale:

STRING=`echo 'dit /ZOU/ een test123' | Perl -pe's/ //g;tr/[A-Z]/[a-z]/;s/[^a-zA-Z0-9]//g'`

1
Thomas

Vous pouvez l'exécuter via Perl.

export CLEANSTRING=$(Perl -e 'print join( q//, map { s/\\s+/_/g; lc } split /[^\\s\\w]+/, \$ENV{STRING} )')

J'utilise un sous-shell de style ksh ici, je ne suis pas totalement sûr que cela fonctionne dans bash.

C'est la bonne chose à propos de Shell, c'est que vous pouvez utiliser Perl, awk, sed, grep ...

1
Axeman

Pour Bash> = 4.:

CLEAN="${STRING//_/}" && \
CLEAN="${CLEAN// /_}" && \
CLEAN="${CLEAN//[^a-zA-Z0-9]/}" && \
CLEAN="${CLEAN,,}"

Ceci est particulièrement utile pour créer des noms de conteneurs par programme à l'aide de docker/podman. Cependant, dans ce cas, vous souhaiterez également supprimer les traits de soulignement:

# Sanitize $STRING for a container name
CLEAN="${STRING//[^a-zA-Z0-9]/}" && \
CLEAN="${CLEAN,,}"
0
anon_stackoverflock

Après quelques recherches, il semble que tr est en effet le moyen le plus simple:

export CLEANSTRING="`echo -n "${STRING}" | tr -cd '[:alnum:] [:space:]' | tr '[:space:]' '-'  | tr '[:upper:]' '[:lower:]'`"

Rasoir d'Occam , je suppose.

0
Devin Reams