我正在尝试学习如何在bash中使用数组。我正在编写一个脚本,要求用户提供三个数字,并确定最大数字是什么。我希望脚本强制用户只输入数值。而且,我希望这三个数字应该是不同的。我正在使用数组来存储用户输入。这就是我到目前为止所做的:
## declare variables
order=("first" "second" "third")
answers=()
RED='\033[0;31m'
NC='\033[0m' # No Color
numbersonly() {
if [[ ! $1 =~ ^[0-9]+$ ]]; then
echo "${RED}$1 is not a valid number.${NC}"
else
answers+=("$input")
break
fi
}
inarray(){
for e in ${answers[@]}; do
if [[ $1 == $e ]]; then
echo "${RED}Warning.${NC}"
fi
done
}
readnumber(){
for i in {1..3}; do
j=$(awk "BEGIN { print $i-1 }")
while read -p "Enter the ${order[$j]} number: " input ; do
inarray $input
numbersonly $input
done
done
}
displayanswers(){
echo "Your numbers are: ${answers[@]}"
}
biggestnumber(){
if (( ${answers[0]} >= ${answers[1]} )); then
biggest=${answers[0]}
else
biggest=${answers[1]}
fi
if (( $biggest <= ${answers[2]} )); then
biggest=${answers[2]}
fi
echo "The biggest number is: $biggest"
}
main(){
readnumber
displayanswers
biggestnumber
}
main
现在,当用户输入之前输入的数字时,我可以让脚本显示警告,但是如果用户输入已经存在,我似乎无法找到保留在while循环中的正确语法进入。想法?
答案 0 :(得分:0)
我找到了解决方法。我的问题是双重的:1)我没有意识到如果你有一个嵌套在while循环中的for循环,你需要两个break语句来退出while循环; 2)在同一个while循环中有两个函数使得很难控制发生了什么。通过将inarray()和numbersonly()合并到一个新函数中,我解决了双条件问题。新功能如下所示:
testing(){
for item in ${answers[*]}
do
test "$item" == "$1" && { inlist="yes"; break; } || inlist="no"
done
if [[ $inlist == "yes" ]]; then
echo "${RED}$1 is already in list.${NC}"
else
if [[ ! $1 =~ ^[0-9]+$ ]]; then
echo "${RED}$1 is not a valid number.${NC}"
else
answers+=("$input")
break
fi
fi
}
答案 1 :(得分:-2)
这里没有太多的研究就是从屏幕上跳下来跟随我。当心我还没有真正测试过它......调试是留给学生的一项练习。
建议使用较新的“函数”定义,因为您可以声明局部变量。 ()定义不允许本地化变量。
function inarray { local e; #don't muck up any variable e in caller ... }
要计算值,请避免额外的awk并使用j=$(( i - 1 ));
biggestnumber
应该使用循环。
总体评论:
nummax=3; #maximum value defined in just one place # loop this way... showing optional {} trick for marking larger loops for (( n = 0; n < nummax; ++n )); do { nx=$(( 1 + n )); #1 based index } done;
提示:一旦所有输入都存在,应该停止输入循环。还可以添加:
if [ "" == "${input:-}" ]; then break;
for (( a = 0; a < ${#answer[*]}; ++a )); do
如果变量值为空或包含许多shell元字符(如空格),请注意大量使用双引号以避免语法错误。我不能告诉你我通过在现有代码中添加引号来修复了多少错误报告。
[[...]]表达式使用文件名测试,而不是正则表达式。您可以使用[[ ! $1 =~ ^[0-9]+$ ]];
离[[ "$1" != [0-9]* ]] && [[ "$1" != *[^0-9]* ]]
最近的地方。
但我怀疑 ! expr >/dev/null "$i" : '[0-9][0-9]*$';
更像是你想要的“expr”使用正则表达式。不要包含在[] s中。使用[0-9] [0-9] *而不是[0-9] +作为“+”在UNIX正则表达式的所有方言中给出了混合成功。