【问题标题】:Storing data in an array (bash scripting)将数据存储在数组中(bash 脚本)
【发布时间】:2015-05-12 23:06:55
【问题描述】:

我想询问用户的输入,例如:

Echo "Please enter name: "
read name 
read -r -p "Is this a costumer? (Y/N)" response;
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
then 
    echo "Please enter name: "
    read name
    AreYouDone
else
    "Please enter  name "
    read name2
    AreYouDone
fi

echo $name is a costumer  
echo $name2 is an employer

我们的想法是不断询问 namename2 并根据 Y/N 答案在最后打印它们。

但是如何将它们存储到不同的变量中呢?**

可能有 20 个名字,有些是客户,有些是雇主。

附注:

为了消除任何混淆,如果有的话,AreYouDone 只是一个函数,当客户完成并已经实现时,它会退出程序。

谢谢。

【问题讨论】:

标签: bash unix scripting


【解决方案1】:

听起来您需要两个数组——一个客户数组和一个雇主数组。

declare -a customers=( ) employers=( )
while ! AreYouDone; do
  echo "Please enter name: "
  read name 
  read -r -p "Is this a costumer? (Y/N)" response;
  if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then 
      customers+=( "$name" )
  else
      employers+=( "$name" )
  fi
done

然后,按类型打印所有名称:

printf '%s is a customer\n' "${customers[@]}"
printf '%s is an employer\n' "${employers[@]}"

更好的方法是使用关联数组来存储每个名称的类型信息。

declare -A names=( )
while ! AreYouDone; do
  read -r -p "Please enter name: " name
  read -r -p "Is this a customer? " type
  if [[ $response = [Yy][Ee][Ss] ]]; then
    names[$name]=customer
  else
    names[$name]=employer
  fi
done

for name in "${!names[@]}"; do
  echo "$name is a ${names[$name]}"
done

另外:如果你想更好地控制 AreYouDone 之后发生的事情,最好这样写:

AreYouDone() {
  read -r -p 'Are you done?'
  case $REPLY in
    [Yy]*) return 0 ;;
    *)     return 1 ;;
  esac
}

...让它根据用户是否想要退出返回一个真或假值,而不是让它自己退出。

【讨论】:

  • 好东西;我建议将Echo 更改为echo,因为Echo 至少在默认情况下仅适用于不区分大小写的文件系统(通过调用echo 的实用程序形式而不是shell 内置)。
  • 嘿!我假设用户有自己的助手,但这确实是更可能的解释。
  • 我收到line 14: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] 这是我的错误吗? (通过使其 -a 解决)。
  • 我也使用了您的 AreYouDone() 实现,但它说找不到命令。 AreYouDone: command not found
  • @user3610137,回复:AreYouDone,你把它放在哪里以及如何称呼它很重要。特别是,它需要位于顶部。
【解决方案2】:

声明数组/s。

例子:

declare -a names
for ((i=0;i<20;i++));do
  read -rp "Enter name: " 'names[i]'
  echo "${names[i]}"
done

另外(来自评论): 你可以用你得到的输入用另一个for循环构造一个完整的句子:

for ((i=0;i<${#names[@]};i++));do
  fullsentence+="Name is ${names[$i]} "
done
echo "$fullsentence"

由于names 是一个索引数组,您可以使用${names[$i]} 在某个索引处访问它的值,其中$i 是索引。 ${#names[@]} 是数组的大小。

【讨论】:

  • 谢谢!但是,如果我想在循环外输出数据,我该怎么做呢?那可行吗?我问的原因是在此之前还有其他信息。就像我在开始时要求年龄组 ONCE 一样,然后在最后我正在对完整句子中给出的所有信息进行回声。喜欢:Age Group: 16-24 Name John is an employer Name Joe is a costumer Name Alex is a costumer
  • @user3610137,是的,当然这是可行的,您可以应用多种方法,但如果您打算使用多个索引数组(年龄、姓名等),那么算术 for 循环将是更好的选择。我已经添加了一个示例,希望您可以使用它来满足您的特定需求
  • 你忘了在那里转义[。应该是read -rp "Enter name: " 'names[i]'
  • 确实如此。启用nullglob 进行测试,不引用的结果特别明显。 :)
猜你喜欢
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
相关资源
最近更新 更多