2010-02-17 9 views
7

he cogido el error de programación funcional, por lo que, naturalmente, no es lo suficientemente bueno para mí. ;)sentencias case fiesta evalúan en cadenas

Así, en bash se podría escribir:

case $status in 
    "foo") status="bar" ;; 
    "baz") status="buh" ;; 
    *) status=$status ;; 
esac 

pero tengo miedo de errores tipográficos, por lo que había prefieren escribir:

status=case $status in 
    "foo") "bar" ;; 
    "baz") "buh" ;; 
    *) $status ;; 
esac 

La segunda forma es no válido dado que el caso se evalúa como el código de salida del último comando ejecutado, que no es lo que estoy buscando.

¿Hay pequeños intentos para lograr lo que yo am buscando?

+0

simplemente que desean escribir una función? – thecoshman

+0

Si le tienen miedo a los errores tipográficos, use ['set -u'] (https://sipb.mit.edu/doc/safe-shell/) al comienzo de su programa. – ceving

Respuesta

9

Si está seguro de estado sólo será una línea, se podría hacer algo como esto con SED:

status=$(echo "$status" | sed -e 's:^foo$:bar:' -e 's:^baz$:buh:') 

También puede ser capaz de conseguir algo para trabajar con la sustitución integrado de fiesta. Este casi obras (no sé de alguna manera de obtener coincidencia exacta solamente):

status=${status/foo/bar} 
status=${status/baz/buh} 

Si su objetivo es sólo para ser más "funcional" (y no para que su código sea más errata a prueba), usted puede hacer esto:

status=$(
    case "$status" in 
    ("foo") echo "bar" ;; 
    ("baz") echo "buh" ;; 
    (*) echo "$status" ;; 
    esac) 

Aunque honestamente, bash es probablemente una de las peores lenguas para tratar de ser funcional en fue realmente diseñado con una mentalidad más necesario, como lo demuestra el hecho de que se puede. Componer expresiones fácilmente ¿Ve en el segundo fragmento de código cómo tuve que dividirlo en dos declaraciones separadas? Si fiesta fueron diseñados para ser funcionales que sería capaz de escribir algo como esto en su lugar:

status=${{status/baz/buh}/foo/bar} 

Pero eso no trabajo.

me gustaría sugerir utilizando sólo golpe para las escrituras más simples y más complicado para el uso cosas algo así como Python o Ruby. Le permitirán escribir más código funcional sin tener que luchar constantemente con el idioma.

+0

Forma de no responder la pregunta y agregar mucha información irrelevante. – mbac32768

+0

zsh le permitirá hacer expansiones de parámetros anidados como su último ejemplo. –

+9

@ mbac32768 por lo que puedo decir, respondí tu pregunta, tres veces de hecho. Si no está de acuerdo, tal vez necesite volver a formular su pregunta, o al menos podría explicar por qué estas soluciones no funcionan para usted. Poner sarcasmo cuando alguien pone esfuerzo en tratar de ayudarte es una especie de cojera. –

-1

Bash 4 tiene matrices asociativas:

# setup 
unset vals i 
indices=(foo baz) 
val=(bar buh) 
declare -A vals    # associative 
for index in ${indices[@]} 
do 
    vals[$index]=${val[i++]} 
done 

$ # demos 
$ status="foo" 
$ status=${vals:-$status} 
$ echo $status 
bar 
$ status="not found" 
$ status=${vals:-$status} 
$ echo $status 
not found 
+0

¿Es así como se supone que debes inicializar matrices asociativas en bash4? –

+1

@Charles: Es una manera que es conveniente para esta demostración. Podría haber hecho 'para index in foo baz' por ejemplo, en lugar de usar una matriz. O hecho una asignación masiva directa o leer desde un archivo. ¿Qué es en particular por lo que preguntas? –

2
status="baz" 
status=$(case $status in 
    "foo") echo "bar" ;; 
    "baz") echo "buh" ;; 
    *) echo $status ;; 
esac) 
echo "status: $status" 

salida

$ ./shell.sh 
status: buh 
+1

Ese es el tercer fragmento que publiqué, pero con errores de sintaxis. (Los parientes cercanos dentro de '$ (...)' confunden bash, por lo que necesita usar el paréntesis abierto opcional en cada caso.) –

+0

¿qué quiere decir confundir a bash? – ghostdog74

+0

bien, supongo que estás usando bash <4.0. En 4.0, creo que esto es fijo. – ghostdog74