2008-09-18 16 views
41

estoy buscando la mejor manera de tomar una entrada sencilla:En un script bash, ¿cómo saneo la entrada del usuario?

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

y limpiarlo mediante la eliminación de los caracteres no alfanuméricos, inferior (de casos), y la sustitución de los espacios por guiones bajos.

¿El pedido es importante? ¿Es tr la mejor/única forma de hacerlo?

Respuesta

41

Como señala dj_segfault, el shell puede hacer la mayor parte de esto por usted. Sin embargo, parece que tendrás que recurrir a algo externo para encordar la cadena. Para esto tienes muchas opciones, como las de Perl de una línea anterior, etc., pero creo que tr es probablemente la más 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` 

El orden aquí es algo importante. Queremos deshacernos de los guiones bajos, además de reemplazar los espacios con guiones bajos, por lo que debemos asegurarnos de quitar los guiones bajos primero. Al esperar para pasar las cosas hasta el final, sabemos que solo tenemos caracteres alfanuméricos y de subrayado, y podemos estar seguros de que no tenemos espacios, por lo que no tenemos que preocuparnos por los caracteres especiales que interpreta el intérprete de comandos.

+1

Nota para el lector: Si tiene problemas para hacer esto, revise su shebang para ver si está llamando a bash o sh, y cómo interpreta su sistema 'sh'. –

+2

A partir de Bash 4, también puede hacer modificaciones de casos. 'minúsculas = $ {CLEAN ,,}' [Bash Hackers Wiki] (http: //wiki.bash-hackers.org/syntax/pe) explica las expansiones de parámetros en una forma * más legible para los humanos que las páginas man. – toxalot

+0

Buen trabajo. No estaba al tanto de estas características de shell. ¡Gracias! Acabo de descubrir que zsh le permite anidar * realmente todo esto, para que pueda hacerlo en una sola línea: 'echo -n $ {$ {$ {str // _ /} ///_} // [^ a-zA-Z0-9 _] /} | tr A-Z a-z' ..no recomiendo poner algo incomprensible en un script. :) (editar: formato) –

0

Después de un poco de mirar a su alrededor parece tr es de hecho la forma más sencilla:

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

Occam's razor, supongo.

+0

si establece 'STRING = $ (rm/tmp/*)', si hace eco de $ STRING antes de la limpieza, ejecutará el subconjunto y eliminará su/tmp/content ... por lo que necesita desinfecte ANTES de que se haga eco. – higuita

1

rápida y sucia:

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

+0

No había visto su solución cuando fui a trabajar en la mía. – Axeman

1

Se puede ejecutar a través de Perl.

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

Estoy usando ksh-style subshell aquí, no estoy totalmente seguro de que funcione en bash.

Eso es lo bueno de la cáscara, es que se puede utilizar perl, awk, sed, grep ....

29

Bash puede hacer todo esto por sí mismo, muchas gracias. Si nos fijamos en la sección de la página de manual de expansión Parámetro, verá que esa fiesta se ha incorporado en sustituciones, subcadena, recortar, rtrim, etc.

Para eliminar todos los caracteres no alfanuméricos, hacer

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

Eso es la navaja de Occam. No es necesario iniciar otro proceso.

+0

Bien puesto, gran respuesta. Estaba usando la expansión de parámetros sin siquiera darme cuenta. –

+2

Es una buena respuesta para un subconjunto de las especificaciones, pero no cambia los espacios para subrayar. – Axeman

Cuestiones relacionadas