Solicitar al usuario un tipo de archivo en un bucle while

Solicitar al usuario un tipo de archivo en un bucle while

Estoy modificando un script para que le solicite al usuario un archivo de un tipo específico. Si el archivo ingresado no coincide con el tipo de archivo específico, entra en un bucle while y se repite hasta que el usuario ingresa el archivo correcto.

En este caso, le pido al usuario un .ziparchivo en:

read -p "Enter zip file: " package1
 while [ package1 != *.zip ] ; do
     read -p "Please enter file ending in '.zip': " package1
 done <<< package1
echo $package1

He tenido errores hasta este momento. Ahora, aparece un cursor en blanco, sin resultados. Ya sea que ingrese *.zipo no, pasa a la siguiente línea con un cursor en blanco y sin salida.

¿Pensamientos?

EDITAR:

Muy bien, he decidido seguir el selectbucle y es una opción mucho mejor que whileen este caso.

Pero, ¿qué pasaría si ese ziparchivo (o cualquier tipo de archivo solicitado) pudiera estar en cualquier otro directorio? Quiero que dé la opción de cambiar de directorio mientras estoy en el select-loopShell.

Lo intenté hasta ahora:

echo Select zip file:
                options=(".." *.zip)
                select package1 in "${options[@]}" ; do
                        case $package1 in
                                1 ) cd ..; echo Select zip file: ;;
                                # Different Directory ) ;;
                                * ) break ;;
                        esac
                done

Pero el bucle no volverá a mostrar los elementos del menú después de cambiar de directorio. No estoy seguro de cómo ofrecer al usuario cdun camino totalmente diferente al ../que quiere, ni para qué usarlo.

"All other existing \# file items" ) ... ; break;;

dentro decase

Respuesta1

Hazlo lógicamente más fácil examinando solo la extensión final:

while [ "${package1##*.}" != "zip" ]
do
    read -e -p "Specify a .zip file: " package1
done
echo $package1

Respuesta2

Se ha publicado una solución más elegante, pero creo que es importante señalar algunos de los errores que provocan que el script original falle y cómo solucionarlos.

Primero, cuando estés probando la variable package1en tu bucle while, debes colocar el $delante de ella para poder leer los datos reales almacenados en esa variable.

A continuación, utilícelo [[...]]en lugar de [...]en su prueba de bucle while, ya que esto le permite hacer coincidir el patrón usando su comodín *. Sin embargo, esto solo funciona en bash, no en sh. Por favor miraesteResponda para obtener una explicación detallada del uso de [[...]]versus [...].

Por último, no es necesario pasar la cadena <<< package1al final del ciclo while.

Aquí hay una versión modificada de su script que funciona según lo previsto.

#!/bin/bash

read -p "Enter zip file: " package1
while [[ "$package1" != *.zip ]]; do
    read -p "Please enter file ending in '.zip': " package1
    done 
echo $package1

Respuesta3

Nunca haga que el usuario escriba las rutas de los archivos de forma interactiva. Es más fácil para ellos llamar a su secuencia de comandos con los nombres de ruta de sus archivos Zip en la línea de comando de la secuencia de comandos. Esto les permite utilizar la función de finalización de nombres de archivos y los patrones globales de nombres de archivos del shell.

El script se llamaría usando, por ejemplo,

./myscript /some/path/myarchive.zip

o

./myscript folder/archive-*.zip

o similar.

En el guión, harías

#!/bin/bash

for archive_path do
    printf 'Processing archive "%s"...\n' "$archive_path"

   # code to process "$archive_path" goes here
done

El bucle en el script recorrería todos los argumentos pasados ​​al script y, en cada iteración, "$archive_path"sería el nombre de ruta de un archivo individual pasado al script.

No es necesario verificar si el nombre del "$archive_path"archivo termina con una cadena en particular, ya que es posible que las herramientas que usaría en el archivo ni siquiera se preocupen por el sufijo del nombre del archivo. Si lo hacen, fallarán con el código de salida apropiado, que usted podría detectar fácilmente:

if ! unzip "$archive_path"; then
    printf 'Failed to run unzip on "%s"\n' "$archive_path" >&2
    exit 1
fi

Si lo usa set -een el script (probablemente como su primera declaración), saldrá automáticamente cuando cualquier comando (que no sea parte de una declaración condicional) regrese con un código de salida distinto de cero.

set -e

# The following would terminate the script if it failed:
unzip "$archive_path"

Con respecto a su "edición" agregada: lo que está haciendo allí es comenzar a implementar una herramienta de exploración de archivos o un administrador de archivos para seleccionar archivos Zip. Dependiendo de para qué desee utilizar este código, esto puede ser excesivo.

Respuesta4

Si desea que el usuario seleccione uno deexistentefiles, lo usaría selecten lugar de read, para permitir que el usuario seleccione de una lista, en lugar de escribir un nombre de archivo que quizás no sepa exactamente.

select package1 in *.zip; do
    break;
done
echo "$package1"

Al usuario se le presentará una lista y escribirá el número.

información relacionada