【问题标题】:Unix Loop variablesUnix 循环变量
【发布时间】:2017-05-03 11:45:02
【问题描述】:

我需要您的帮助来确定下面的问题,

我的意图是循环输入值,同时检查输入值是否为 [0-9],然后将其保存到文件中,然后对其输出进行排序。

我的问题是,每当我运行脚本时,保留为 1 2 3 4 5 的值不是我输入的值,你能帮我解决这个问题吗?我认为条件语句中的变量声明存在问题,但我不知道任何解决方法。

#!/bin/bash -x

echo > save.txt
validnum='0-9'

   for ((i=1;i<=5;i++))
   do
    read -p "Please enter number $i: " num_$i
    if [[ ! $num_$i =~ [^$validnum$] ]] && [[  $num_$i == "" ]]
    then
            echo "Input numbers have been validated.."
            echo $num_$i >> save.txt
    else
            echo "INVALID CHARACTERS IDENTIFIED.."
            echo "Please review your Input Values"
            exit 0
    fi
done
echo "Sorting values.."
echo "Below are the sorted values"
echo `cat save.txt | sort -n`

这是我运行脚本时的扩展版本。

+ echo
+ validnum=0-9
+ (( i=1 ))
+ (( i<=5 ))
+ read -p 'Please enter number 1: ' num_1
Please enter number 1:
+ [[ ! 1 =~ [^0-9$] ]]
+ [[ ! 1 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 1
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 2: ' num_2
Please enter number 2:
+ [[ ! 2 =~ [^0-9$] ]]
+ [[ ! 2 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 2
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 3: ' num_3
Please enter number 3:
+ [[ ! 3 =~ [^0-9$] ]]
+ [[ ! 3 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 3
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 4: ' num_4
Please enter number 4:
+ [[ ! 4 =~ [^0-9$] ]]
+ [[ ! 4 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 4
+ (( i++ ))
+ (( i<=5 ))
+ read -p 'Please enter number 5: ' num_5
Please enter number 5:
+ [[ ! 5 =~ [^0-9$] ]]
+ [[ ! 5 == '' ]]
+ echo 'Input numbers have been validated..'
Input numbers have been validated..
+ echo 5
+ (( i++ ))
+ (( i<=5 ))
+ echo 'Sorting values..'
Sorting values..
+ echo 'Below are the sorted values'
Below are the sorted values
++ cat save.txt
++ sort -n
+ echo 1 2 3 4 5
1 2 3 4 5

【问题讨论】:

  • 您不能像使用num_$i 那样定义动态变量。可能最好使用数组
  • 或者根本不使用动态变量。只需将 num 单独用作变量即可。在这种情况下看不出需要动态变量。
  • 对替换动态变量有什么建议吗?我还没有尝试过数组,不过我目前正在阅读它
  • 从技术上讲,您可以使用间接参数扩展来访问变量,尽管它很笨拙。 tmp=num_$i; if [[ ! ${!tmp} =~ ^$validnum$ ]] &amp;&amp; [[ ${!tmp} == "" ]]。最好认识到循环的每次迭代都不需要单独的变量。
  • @ZaCkDelaCruz,这里为什么声明 [[ ! $num_$i =~ [^$validnum$] ]] 不起作用?因为$num_$i 扩展了两个变量num_i。因为名称 num_ 在 Bash 中是一个有效的变量名称。所以它会解析它们是两个变量。但是如果你用括号括起来${num_$i} 将不起作用。因为它会抱怨bad substitution 错误。如果您希望它起作用,您可以使用间接引用var="num_$i" ; echo ${!var} 会起作用。请参考Bash dynamic variable names

标签: bash shell unix scripting


【解决方案1】:

我认为您只需要以下内容,

validnum='[0-9]'

read -p "Please enter number $i: " num

if [[ $num =~ ^$validnum{1}$ ]]; then
# rest of the code

匹配来自0-9单个 数字。请记住,我已经在变量validnum 中移动了括号表达式,它比您的原始版本更可读。将此 sn-p 插入您的代码应该可以解决您的问题。

正如在 cmets 中所讨论的,您不需要使用动态变量来满足您的这一要求。


OP 要求解释正则表达式,

RegEx demo

引用上面的正则表达式页面,解释正则表达式^[0-9]{1}$

^ 断言字符串开头的位置

匹配下面列表中的单个字符[0-9]{1}

{1} 量词 — 只匹配一次(无意义的量词)

0-9 0 (ASCII 48)9 (ASCII 57) 之间的单个字符(区分大小写)

$ 断言位置在字符串的末尾,或者在字符串末尾的行终止符之前

【讨论】:

  • 感谢您的帮助,我按照之前关于动态变量的 cmets 并得到了正确的值。我不明白 ^$validnum{1}$ 中的 1 .. 它有什么作用?是输入值的长度吗?
  • @ZaCkDelaCruz:看我的更新,看看对你有没有帮助
猜你喜欢
  • 2011-01-28
  • 1970-01-01
  • 2012-04-19
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多