3 votes

Comment inverser les nombres lors de l'utilisation de la commande "select" de l'interpréteur de commandes ?

V.sh

select f in "$@" ; do
    echo $f
done

v.sh a b c Résultat ci-dessous :

1) a
2) b
3) c
#? 

Mais je veux que ce soit ci-dessous et que je puisse sélectionner les options.

3) a
2) b
1) c
#? 

Comment résoudre ce problème de manière simple ? Merci d'avance.

2voto

George Vasiliou Points 4142

Il n'est pas possible d'inverser la numérotation automatique des select mais vous pouvez inverser les arguments, ce qui revient au même (logiquement).

Ce test en une ligne fonctionne correctement dans mon bash et les sélections effectuées correspondent à l'élément inversé correct :

$: function test { select f in $(echo $@|rev) ;do echo $f;done;};test a b c
1) c
2) b
3) a
#? 1
c
#? 2
b
#? 3
a

PS : Dans votre script vous n'avez pas besoin de la fonction. Vous appliquez simplement

select f in $(echo $@|rev) ;do
    echo $f
done

Mise à jour
Comme indiqué dans les commentaires, l'utilisation de rev pour inverser les arguments est valable pour les arguments à un seul caractère comme dans l'exemple de l'OP ( a b c ).
Si un argument est composé de plus de caractères (c.-à-d. cd ) alors rev va également inverser cet arg (c'est-à-dire vers dc ).

Dans ce cas, il est plus sûr de stocker les arguments dans un tableau dans l'ordre inverse, et ensuite Select fera référence à ce tableau inversé comme ceci :

$: function test { local arr;for ((i=${#@};i>0;i--));do \ 
arr+=("${@:$i:1}");done;select f in "${arr[@]}";do echo "$f";done;};test a b cd
1) cd
2) b
3) a
#? 1
cd

En outre, il convient d'être prudent lors de l'utilisation de * comme argument . Il doit être cité (c'est-à-dire '*' ) sinon bash l'étendra au contenu du répertoire de travail actuel. Cette limitation s'applique même dans le tout premier exemple de l'OP.

1voto

mklement0 Points 12597

Comme indiqué, vous ne pouvez pas modifier select mais vous pouvez créer une numérotation personnalisée. select la mise en œuvre :

#!/usr/bin/env bash

# Custom `select` implementation that prints the menu items
# passed as arguments with reverse numbering, prompts for a selection,
# and outputs the selected item.
customSelect() {

  local item i=0 numItems=$# 

  # Print menu items with reverse numbering.
  for item; do
    printf '%s\n' "$((numItems - i++))) $item"
  done >&2 # Print to stderr, as `select` does.

  # Prompt the user for the index of the desired item.
  while :; do
    printf %s "${PS3-#? }" >&2 # Print the prompt string to stderr, as `select` does.
    read -r index
    # Make sure that a valid index was entered.
    (( index >= 1 && index <= numItems )) || { echo "Invalid selection." >&2; continue; }
    break
  done

  # Determine selected item by index entered and print it to stdout.
  printf %s "${@: numItems - index + 1 : 1}"

}

# Present the custom menu and prompt for a selection.
selectedItem=$(customSelect "$@")

# Process the selected item.
case $selectedItem in
  # YOUR HANDLERS HERE.
  *) # Sample handler
    echo "Selected item: [$selectedItem]"
    ;;
esac

Coup de chapeau à chepner pour son aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X