如何获取用户的多个输入并转换为查找值并将它们添加到变量的字符串?

如何获取用户的多个输入并转换为查找值并将它们添加到变量的字符串?

我有一个脚本,它接受用户的输入(选项 1、2、3 等)来选择要部署到远程服务器的文件。我希望用户能够输入多个选项(例如 2,3),而不是用户多次运行此脚本,因此,这些条目会将文本添加到变量中,然后在主函数中引用该变量。

我尝试对这些进行求和并使输入与总和相匹配,但是,如果我们有许多工件要放入此列表中,则选项 5 将部署一件事,而选项 2,3 将以不同方式部署,但加在一起将部署与选项 5 相同的内容这是不可接受的。

例如,这就是我当前设置的,我只是匹配用户输入的字符串(删除空格后,如果有的话)并运行该选项。这对于只有 2 或 3 个工件来说是可以的,但是,当列表变长时,选择就会呈指数级增加。

#!/bin/sh

export alltags="all"
export tag1="artifact1"
export tag2="artifact2"
export tag3="artifact3"

deployment_tag=""

function updateArtifacts

{
   cp -r /path/to/artifact/artifact.zip --tags "\"${deployment_tag}"\"
}

echo "Enter the number of the artifacts you would like to deploy"
"1. artifact1"
"2. artifact2"
"3. artifact3"

read -p " " num

trimNum=`echo $num | sed 's/ //g'`

if [ "$trimNum" == "1" ]; then
       $deployment_tag+="$alltags"
       echo "Updating all artifacts"
       updateArtifacts
elif [ "$trimNum" == "2" ]; then
       $deployment_tag+="$tag1"
       echo "Updating artifact 1"
       updateArtifacts
elif [ "$trimNum" == "2,3" ]; then
       $deployment_tag+="$tag1,$tag2"
       echo "Updating artifact 1 and 2"
       updateArtifacts
else
     echo "aborted, please enter a valid selection"
fi

我知道我缺少选项,但这只是举一个简短的例子。我知道这很冗长,我感谢任何意见。

答案1

以下是如何使用数组来执行此操作的示例,并可以选择从命令行获取 args。如果未提供参数,则提示输入工件标签。

我最终没有使用case语句,因为事实证明,通过将所有标签放入数组中,就不需要它了。

#!/bin/bash

# dup stdout so we can print prompts etc in the ask function
# anything printed to >&3 will go to the terminal (i.e. original stdout)
# anything printed to stdout will be part of the function's return value
exec 3>&1

tags=( all
artifact1  artifact2  artifact3
artifact4  artifact5  artifact6
artifact7  artifact8  artifact9
artifact10 artifact11 artifact12
artifact13 artifact14 artifact15
)
declare -a deployment_tags
declare -a nums

# comment out or set to zero to disable debugging
debug=1

[ "$debug" = 1 ] && declare -p tags deployment_tags nums

###
### functions
###

print_choices() {
  i=1
  while [ "$i" -lt "${#tags[@]}" ] ; do
    # one per line
    #printf '%i. %s\n' "$i" "${tags[$i]}" >&3
    #let i=i+1

    # or three per line
    for j in 0 1 2; do
      [ -n "${tags[$i]}" ] && printf '%2i. %-12s\t' "$i" "${tags[$i]}" >&3
      let i=i+1
    done
    printf "\n" >&3

  done
}

usage() {
   echo "Usage: $(basename "$0") [n...]"
   echo
   print_choices
   echo "Choose 1 or more, separated by spaces or commas, or 0 for all of the above"
   exit 1;
}

ask() {
  echo "Enter the number of the artifacts you would like to deploy:" >&3
  print_choices
  echo "Choose 1 or more, separated by spaces or commas, 0 for all, or q to quit" >&3

  until [[ "$num" =~ ^[[:space:]0-9,qQ]+$ ]] ; do
    read -r -p "Choose: " num >&3

    [[ $num =~ [qQ] ]] && return 1

    # split into nums array.  if num contains zero ("all"), remove
    # all other choices as they're already included in "all"
    nums=( $(printf '%s' "$num" | sed -e 's/.*0.*/0/; s/,/ /g') )

    # if any of the numbers provided didn't correspond to a valid
    # tag, ask again
    for i in "${nums[@]}" ; do
      [ -z "${tags[$i]}" ] && echo "Invalid choice $i" >&3 && num=""
    done
  done

  echo "${nums[@]}"
}

updateArtifacts() {
   # WTF is the `--tags` argument to `cp`???
   # echo it because it's bogus
   echo cp -r /path/to/artifact/artifact.zip --tags "$@"

  # this function should do something useful with "$@".
}

###
### main code
###

# get the args from the command line, or ask for them if missing.
if [ -n "$*" ] ; then
  # only digits separated by commas or spaces allowed
  [[ "$*" =~ ^[[:space:]0-9,]+$ ]] || usage

  # split into nums array.  if num contains zero ("all"), remove
  # all other choices as they're already included in "all"
  nums=( $(printf '%s' "$*" | sed -e 's/.*0.*/0/; s/,/ /g') )
else
  nums=( $(ask) )
  [ "$?" != 0 ] && echo "Quitting..." && exit 0
fi

[ "$debug" = 1 ] && declare -p nums

# get nums choices into deployment_tags array
for i in "${nums[@]}" ; do
  [ -z "${tags[$i]}" ] && echo "Error: tag $i does not exist!" && exit 2

  deployment_tags+=("${tags[$i]}")
done

[ "$debug" = 1 ] && declare -p deployment_tags

updateArtifacts "${deployment_tags[@]}"

相关内容