¿Cómo enumerar todos los archivos de un directorio junto con un índice para permitir a los usuarios elegir el archivo ingresando el número de índice?

¿Cómo enumerar todos los archivos de un directorio junto con un índice para permitir a los usuarios elegir el archivo ingresando el número de índice?

Tengo varios archivos en un directorio y estoy trabajando en un script bash para enumerar todos los archivos junto con un índice junto a ellos para que los usuarios puedan elegir qué archivo seleccionar según el índice en lugar de escribir el archivo completo. nombre.

Por ej.

main_dir
 - temp_1
 - temp_2

Mi intento:

while [[ 1 ]]; do
        printf "Which file do you want to use? ($(ls -m ${main_dir})) "
        read -r ans
        if [[ -d ${main_dir}/${ans} ]]; then
            break
        else
            echo "[ERROR] Failed to choose. Please choose from ($(ls -m "${main_dir}"))."
        fi
    done

En este caso, la salida es:

Which file do you want to use? (temp_1, temp_2)

Además, el usuario debe ingresar el nombre del archivo para seleccionarlo.

GASTOS ESPERADOS:

Which file do you want to use? 
1. temp_1 
2. temp_2

Y el usuario debería poder elegir un archivo de ambas maneras, ingresando el nombre o el índice.

Respuesta1

recorra * y recuerde los archivos en una matriz:

files=()
i=0
for f in *
do 
  [ -d "$f" ] && continue ## skip directoriries
  files[$i]="$f"
  echo "$i"$'\t'"${files[i]}"
  (( ++i ))
done
if read -p "Which file do you want to use? " ans 
then 
     echo "you choose ${files[ans]}"
     stat "${files[ans]}"
     wc "${files[ans]}"
fi

Respuesta2

Ampliando el comentario de @Cyrus sobre la utilidad de la selectdirectiva de bash....

Si no fuera por su estipulación de poder seleccionar por número o nombre, bash selectpodría ser todo lo que necesita:

$ select name in *; do printf "You chose %s\n" "$name"; done
1) file AA    6) file_E   11) file_J   16) file_O   21) file_T   26) file_Y
2) file_A     7) file_F   12) file_K   17) file_P   22) file_U   27) file_Z
3) file_B     8) file_G   13) file_L   18) file_Q   23) file_V   28) foo.sh
4) file_C     9) file_H   14) file_M   19) file_R   24) file_W
5) file_D    10) file_I   15) file_N   20) file_S   25) file_X
#? 1
You chose file AA
#? 4
You chose file_C
#? 28
You chose foo.sh
#? ^D

Si bien la interfaz puede ser un poco espartana para algunas necesidades, cuando necesita algo rápido y sucio, pero aún así confiable, selectes una herramienta útil para tener en su bolso.

La manpágina de bash cita algunos aspectos del selectcomportamiento de que podemos utilizar:

Luego se muestra el mensaje de PS3 y se lee una línea de la
entrada estándar. Si la línea consta de un número correspondiente
a una de las palabras mostradas, entonces el valor del nombre se establece en
esa palabra. Si la línea está vacía, las palabras y el mensaje se
muestran nuevamente. Si se lee EOF, el comando se completa. Cualquier
otro valor leído hace que el nombre se establezca en nulo. La línea leída
se guarda en la variable RESPUESTA.

Entonces, al poner algún código de soporte alrededor de la llamada a select, esto es posible:

unset name

_PS3="$PS3"
PS3="Which file do you want to use? "

while [ -z "$name" ]
do

    select name in *; do break; done

    if [ -z "$name" ]
    then
        if [ -f "$REPLY" ]
        then
            name="$REPLY"
            printf "You chose by name: '%s'\n" "$name"
        else
            printf "There is no file by that name.\n"
        fi
    else
        printf "You chose by number: '%s'\n" "$name"
    fi

done

PS3="$_PS3"; unset _PS3

Producción:

$ ./foo.sh 
1) file AA    6) file_E   11) file_J   16) file_O   21) file_T   26) file_Y
2) file_A     7) file_F   12) file_K   17) file_P   22) file_U   27) file_Z
3) file_B     8) file_G   13) file_L   18) file_Q   23) file_V   28) foo.sh
4) file_C     9) file_H   14) file_M   19) file_R   24) file_W
5) file_D    10) file_I   15) file_N   20) file_S   25) file_X
Which file do you want to use? 12
You chose by number: 'file_K'
$ ./foo.sh 
1) file AA    6) file_E   11) file_J   16) file_O   21) file_T   26) file_Y
2) file_A     7) file_F   12) file_K   17) file_P   22) file_U   27) file_Z
3) file_B     8) file_G   13) file_L   18) file_Q   23) file_V   28) foo.sh
4) file_C     9) file_H   14) file_M   19) file_R   24) file_W
5) file_D    10) file_I   15) file_N   20) file_S   25) file_X
Which file do you want to use? file W
There is no file by that name.
1) file AA    6) file_E   11) file_J   16) file_O   21) file_T   26) file_Y
2) file_A     7) file_F   12) file_K   17) file_P   22) file_U   27) file_Z
3) file_B     8) file_G   13) file_L   18) file_Q   23) file_V   28) foo.sh
4) file_C     9) file_H   14) file_M   19) file_R   24) file_W
5) file_D    10) file_I   15) file_N   20) file_S   25) file_X
Which file do you want to use? 29
There is no file by that name.
1) file AA    6) file_E   11) file_J   16) file_O   21) file_T   26) file_Y
2) file_A     7) file_F   12) file_K   17) file_P   22) file_U   27) file_Z
3) file_B     8) file_G   13) file_L   18) file_Q   23) file_V   28) foo.sh
4) file_C     9) file_H   14) file_M   19) file_R   24) file_W
5) file_D    10) file_I   15) file_N   20) file_S   25) file_X
Which file do you want to use? file AA
You chose by name: 'file AA'

información relacionada