![enumerar archivos y almacenarlos en variables](https://rvso.com/image/38694/enumerar%20archivos%20y%20almacenarlos%20en%20variables.png)
Soy nuevo en la programación de shell. Mi objetivo es darle al usuario una selección de qué archivo debe ejecutarse. Capto todos los scripts disponibles en una var con:
var=$(find script*)
Hasta ahora todo bien, este es el resultado:
echo $var
script1 script2 script3 scr...
ahora quiero almacenar cada archivo en una variable única para ejecutarlo en una selección posterior
select SEL in script1 script2 script3 ..........
case $SEL in
$Script1) echo ($Script1 will start) && ./$script1 ;;
$Script2) echo ($Script2 will start) && ./$script2 ;;
$Script3) echo ($Script3 will start) && ./$script3 ;;
$Sc..) echo ($Scr.... will start) && ./$scrip.... ;;
$Sc...) echo ($Sc...... will start) && ./$scrip..... ;;
*) echo "choose on of the availabel files";;
esac
done
No tengo idea de cómo debo separar todos los archivos si no sé cuántos y la longitud exacta de cada archivo.
Intenté dividir con echo ${var[1]} y echo $var[1] pero esto no funciona. Recibo una salida vacía o la cadena completa.
Respuesta1
Tu primera línea:
var=$(find script*)
es solo hacer var
una variable de cadena única con todo script*
en ella. Esnouna matriz, por lo que no podemos indexarla []
como usted desea.
En realidad, el script*
shell lo expande, por lo que find
no hace nada allí (a menos que sean directorios, lo cual no parece que lo sean): simplemente obtiene todos los nombres de archivos como argumentos, verifica que existan y los imprime directamente. volver a salir. El caparazón realmente hace todo el trabajo.
En lugar de eso, podemos hacer unaformación, y podemos usar el shellexpansión globaldirectamente para poblarlo:
files=(script*)
Cuando ponemos el inicializador (el lado derecho de =
) entre paréntesis, estamos creando una matriz, que contiene múltiples valores por separado. script*
se expandirá a cada nombre de archivo comenzando con script
el directorio actual. Si hay espacios en los nombres de los archivos, no harán que las palabras se dividan como lo harían con los comandos (comillas invertidas o $()
) dentro del inicializador de la matriz.
En este punto podemos leer en algunas entradas del usuario:
select SEL in "${files[@]}"
do
if ! [ "$SEL" ]
then
echo "Choose one of the available files."
continue
fi
echo "$SEL will start"
"./$SEL"
break
done
Escribimos "${files[@]}"
para expandir toda nuestra gama de nombres de archivos de manera limpia para dar a select
. Al usuario se le ofrecerá una selección de archivos y luego ingresamos al do...done
bloque.
Si $SEL
está vacío, el usuario eligió una entrada que no existe, por lo que imprimimos el mensaje y continue
se le pide que elija nuevamente.
De lo contrario, recibiremos echo
la notificación de que el script se iniciará y ejecutará. Citamos el nombre "./$SEL"
en caso de que el nombre del script tenga espacios, lo que de otro modo haría que el nombre del comando se tratara como ./firstword
, con las palabras restantes como argumentos. break
nos impide volver y preguntarle al usuario nuevamente; si quieres hacer eso, sácalo.
Lo case...of
que estabas usando no parece tener mucho efecto en el ejemplo que das, pero si tienes algún comportamiento separado dependiendo del script elegido (y tiene que estar enestescript), puedes ponerlo dentro del do...done
bloque.
Respuesta2
No estoy 100% seguro de entender completamente lo que quieres hacer, pero esto podría funcionar mejor para ti: en lugar de var=$(find script*) y un caso que podrías usar mejor
for i in `find script*`
do
echo ($i will start)
./$i
done