shell-为(已验证的)提供的数字或数字范围迭代循环

时间:2018-08-29 04:32:44

标签: shell loops scripting posix

我需要接受用户的输入(即“读取”)。

此输入可以是单个正数或数字范围(以X-Y的形式)。

然后,我需要验证此输入并在数字范围内执行迭代循环(如果只有X,则仅执行一次)。

示例:

1)用户提供:“ 8”或“ 8-” 循环仅一次提供数字8

2)用户耗材:“ 13-22”

循环运行11次(13到22),引用数字13。

3)用户耗材:“ 22-13”

大概应该像上面的#2一样...但是我愿意接受其他一些干净的方法来验证输入。

到目前为止,我已经完成了以下工作,虽然我的要求不是很干净,完整,甚至100%正确,但它表明了我要努力的方向和想法:

echo "line?"; read -r deleteline
case "$deleteline" in
        ''|*[!0-9\-]*)   echo "not a number";;
        [1-9]|[1-9][0-9]*);;
esac


deleteline_lb=$(echo $deleteline|awk -F "-" '{print $1}')
deleteline_ub=$(echo $deleteline|awk -F "-" '{print $2}')

if [ ! $deleteline_lb = "" ] && [ ! "$deleteline_ub" = "" ]; then
        delete_line_count=1
        delete_line_count=$(expr $deleteline_ub - $deleteline_lb)
        if [ $delete_line_count -le 0 ]; then
                delete_line_count=1
        fi
fi

i=1; while [ $i -le $delete_line_count ]; do
  echo $deleteline_lb $i
  i=$(($i + 1))
done

这需要在sh中运行,不支持seq之类的东西-因此请坚持使用posix兼容方法...


为澄清起见,我正在尝试执行以下操作(伪代码): 1)接受用户的输入 2)验证输入的格式是否为“#”或“#-#”(范围)。 3)根据正确/不正确的输入执行选择的(任意)代码路径。 4)如果给出了单个#,则将其存储到变量中以执行以后的操作。 5)如果给定范围,则将两个数字都存储在变量中,以便能够对从低到高的数字进行运算。更具体地说,它将是“((较高的#)-(较低的#)+ 1”。因此,如果范围是12-17,那么我们需要对12、6x进行运算。 (17-12 + 1)。 IOW,包括12-17。 6)还需要一种易于表示数据集是范围还是单个数字的方法,以便可以轻松分支到每个数据集的代码路径。

感谢您的帮助!

更新:

使用我的基本代码,我对其进行了重做(从朋友那里得到了一些输入),并且基本上想到了:

            while true;do
                printf "\\delete lines? [e=Exit] ";read -r deleteline
                case "$deleteline" in
                    [Ee])   break;;
                    *)
                    echo "$deleteline" | egrep -q '^[[:digit:]-]*$' 

                    if [ $? -ne 0 ]; then
                       printf "\\n input is not a number.\\n"
                    else
                        delete_range_start=`echo $deleteline|awk -F "-" '{print $1}'` 
                        delete_range_end=`echo $deleteline|awk -F "-" '{print $2}'` 

                        if [ $delete_range_end -lt $delete_range_start ]; then
                            printf "\\n upper range must be higher than lower range.\\n"
                        else
                            if [ "$delete_range_end" = "" ]; then
                                delete_range_end=$delete_range_start
                            elif [ $delete_range_end -gt $lineNumbers ]; then
                                printf "\\Setting range to last entry\\n"
                            fi
                            break
                        fi  
                    fi
                    ;;
                esac

            done

            deleteline=$delete_range_start
            deleteloop=`expr $delete_range_end - $delete_range_start + 1`

            i=1
            while [ $i -le $deleteloop ]; do
                    # Insert all processing code in here
                    i=`expr $i + 1`
            done    

1 个答案:

答案 0 :(得分:1)

如果您拥有posix兼容的awk,请尝试以下操作:

private void MainForm_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    foreach (var shape in shapeList)
        shape.Draw(g);
}

该脚本检查2个字段(用echo "$userInput" | awk -F- ' ($1+0==$1&&$2+0==$2){ for(i=$1;($1<$2?i<=$2:i>=$2);) print ($1<$2?i++:i--); next } $1+0==$1{ print $1; next } $2+0==$2{ print $2; next } ($1+0!=$1&&$2+0!=$2){ exit 1 }' 分隔)是否为数字。如果是这样,它将以升序或降序方式打印这些数字,具体取决于第一个数字是大于还是小于第二个数字。
如果只有一个输入,脚本只会打印它。
如果该字段都不是数字,则它将以非零值退出。

此脚本可能是这样的shell脚本的验证步骤:

-

示例:

$ cat test.sh
#!/bin/sh
echo -n "range: "
read -r range
validated_input=$(echo "$range" | awk -F- '($1+0==$1&&$2+0==$2){for(i=$1;($1<$2?i<=$2:i>=$2);)print ($1<$2?i++:i--);next}$1+0==$1{print $1;next}$2+0==$2{print $2;next}($1+0!=$1&&$2+0!=$2){exit 1}')
if [ $? -ne 0 ]; then
    echo "Incorrect range" >&2
fi
for i in $validated_input; do
    echo "$i"
done