Como solicitar entrada de um usuário a partir de uma matriz variável ou bash?

0

Em um script bash, como você escreveria o seguinte?

USER_INPUT="1 2 3 4 5"
echo "Please select one of the following values: $USER_INPUT"
Prompt the user to choose a value in $USER_INPUT.
echo "command <user input> <iterate through remaining numbers not selected from $USER_INPUT>

Por exemplo, se o usuário selecionar "2", os seguintes comandos serão executados.

command 2 1
command 2 3
command 2 4
command 2 5
    
por uihdff 30.08.2017 / 07:27

3 respostas

1
#!/bin/bash
PROMPT=(1 2 3 4 5)
for i in ${PROMPT[*]}
do
    printf " %d\n" $i
done
echo "Choose an option: "

read var

unset PROMPT[$var-1]
PROMPT_new=(${PROMPT[@]})

for n in ${PROMPT_new[*]}
do
    echo 'command $var $n'
done
    
por 30.08.2017 / 08:27
2
#!/bin/bash

values=( "Why is" "a raven" "like a" "writing desk?" )

select word in "${values[@]}"; do
    if [[ -z "$word" ]]; then
        printf '"%s" is not a valid choice\n' "$REPLY" >&2
    else
        user_in="$(( REPLY + 1 ))"
        break
    fi
done

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        printf 'You did not pick "%s"\n' "${values[$i]}"
    fi
done

O comando select apresentará ao usuário um menu de opções. Ao escolher um item de menu, $REPLY será o número que o usuário inseriu e $word será o valor no menu correspondente a esse número. Se uma escolha inválida for feita, $word estará vazio.

A segunda parte itera sobre nossa matriz (que corresponde à sua string $USER_INPUT ) usando o loop for semelhante a C em bash . Se chegarmos ao índice que corresponde ao valor escolhido, pulamos ele. Nós imprimimos todos os outros valores do nosso array.

Você pode, obviamente, executar comandos no loop para:

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        printf 'command %s %s\n' "$user_in" "${values[$i]}"
    fi
done

ou até mesmo

for (( i = 0; i < ${#values[@]}; ++i )); do
    if (( i != user_in )); then
        command "${values[$user_in]}" "${values[$i]}"
    fi
done

que tentará executar as coisas reais em $values como um comando.

Testando-o (com a primeira versão do loop):

$ bash script.sh
1) Why is
2) a raven
3) like a
4) writing desk?
#? B
"B" is not a valid choice
#? 0
"0" is not a valid choice
#? 3
You did not pick "Why is"
You did not pick "a raven"
You did not pick "writing desk?"

Se você puder arcar com modificação $values , e quiser apenas mostrar as coisas que o usuário não escolheu, então a segunda parte do script (o loop) pode ser substituída por

unset values[$user_in]
printf 'You did not pick "%s"\n' "${values[@]}"
    
por 30.08.2017 / 08:17
1

Aceite sua entrada na linha de comando, não de forma interativa. (Por favor!)

Isso é bastante simples, eu usaria apenas uma função de shell.

iter_the_command() {
  max=5
  [ "$#" -eq 1 ] && [ "$1" -ge 1 ] && [ "$1" -le "$max" ] ||
    { printf 'Error: please pass a number from 1 to %d\n' "$max" >&2;
      return 1;}
  for i in $(seq "$max"); do
    [ "$i" -eq "$1" ] && continue
    somecommand "$1" "$i"
  done
}

No entanto , tenho uma strong suspeita de que esta é uma questão XY e o que você está realmente tentando fazer seria mais facilmente realizado diretamente. (Em outras palavras, acho difícil imaginar um cenário em que o código acima realmente seja útil e execute uma função necessária, caso contrário, não seria melhor feito.)

    
por 30.08.2017 / 07:49