在bash中生成case范围

在bash中生成case范围,bash,switch-statement,range,Bash,Switch Statement,Range,我想在一个函数中输入两位和三位数字并输出一个大小写范围,即输入33和66并输出3[3-9]|[4-5][0-9]|6[0-6]或输入33和666并输出3[3-9]|[4-9][0-9]|[1-5][0-9][0-9]|6[0-5][0-9][0-6] 关于如何做,有什么想法?谢谢 这里是0-99的最大2位数的情况,我没有使用字符的运算,事实上我尝试过数学运算 以下是一些输出: /range.sh 1 39->0[1-9]|[1-2][0-9]|3[0-9] /range.sh 21 49->2[

我想在一个函数中输入两位和三位数字并输出一个大小写范围,即输入
33
66
并输出
3[3-9]|[4-5][0-9]|6[0-6]
或输入
33
666
并输出
3[3-9]|[4-9][0-9]|[1-5][0-9][0-9]|6[0-5][0-9][0-6]


关于如何做,有什么想法?谢谢

这里是0-99的最大2位数的情况,我没有使用字符的运算,事实上我尝试过数学运算

以下是一些输出:

/range.sh 1 39
->
0[1-9]|[1-2][0-9]|3[0-9]

/range.sh 21 49
->
2[1-9]|[3-4][0-9]

/range.sh 33 66
->
3[3-9]|[4-5][0-9]|6[0-6]

/range.sh 33 99
->
3[3-9]|[4-8][0-9]|9[0-9]

下面是我的代码:range.sh,希望能为您提供一些帮助:

#!/bin/bash

LHS=$1
RHS=$2
B2=10

D2=$(echo "($RHS-$LHS)/$B2" | bc)
if [[ ${D2} -gt 0 ]]; then
  S2=(`seq $(echo "$LHS/$B2" | bc) $(echo "$LHS/$B2+$D2" | bc)`)
  #echo ${S2[@]}
  C=${#S2[@]}
  #echo $C

  L1=$(echo "$LHS%$B2" | bc)
  if [[ ${L1} -lt 9 ]]; then 
    L1R="[${L1}-9]"
  else
    L1R="9"
  fi

  R1=$(echo "$RHS%$B2" | bc)
  if [[ ${R1} -gt 0 ]]; then
    R1R="[0-${R1}]"
  else
    R1R="[0-9]"
  fi

  if [[ ${C} -gt 3 ]]; then
    echo -n $(echo "$LHS/$B2" | bc)$L1R
    echo -n " | "[${S2[1]}-${S2[$C-2]}][0-9]
    echo -n " | "${S2[$C-1]}$R1R
  elif [[ ${C} -eq 3 ]]; then
    if [[ ${S2[0]} -eq 0 ]]; then
      echo -n 0$L1R
    else
      echo -n $(echo "$LHS/$B2" | bc)$L1R
    fi
    echo -n " | "[${S2[1]}-${S2[$C-1]}][0-9]
  fi

else
  echo [$LHS-$RHS]
fi

echo

以下是两位数字的逻辑:

#!/bin/bash
l=$1
h=$2

function get_nearest_upper_10th_mutlitple()
{
    v=$(($1+10))
    echo "${v%?}0"
}
function get_nearest_lower_10th_mutlitple()
{
    v=$1
    echo "${v%?}0"
}

temp="$(printf '%d' $l | wc -m)$(printf '%d' $h | wc -m)"
case $temp in
    11) echo "[$l-$h]"      ;;
    22|12)
        a=$([[ $(($l%10)) -eq 0 ]] && echo $l || echo $(($(get_nearest_upper_10th_mutlitple $l)-1)))
        if [[ $(printf '%d' $a | wc -m) -eq 1 ]]; then
            echo [$l-$a]
        else
            [[ $a -gt $l ]] && echo "${l%?}[${l#?}-${a#?}]" || echo $a
        fi

        b=$([[ $(($h%10)) -eq 0 ]] && echo $h || get_nearest_lower_10th_mutlitple $h)

        x=$((a+1))
        y=$((b-1))
        echo "[$(echo ${x%?}~${y%?} | sed 's/~/\n/g' | sort -n | uniq | paste -s -d '-')][${x#?}-${y#?}]"

        [[ $b -lt $h ]] && echo "${h%?}[${b#?}-${h#?}]" || echo $b
esac
以下是示例输出:

$ ./script.bash 2 8
[2-8]
$ ./script.bash 2 6
[2-6]
$ ./script.bash 2 68
[2-9]
[1-5][0-9]
6[0-8]
$ ./script.bash 23 68
2[3-9]
[3-5][0-9]
6[0-8]
$ ./script.bash 23 99
2[3-9]
[3-8][0-9]
9[0-9]
$ ./script.bash 23 80
2[3-9]
[3-7][0-9]
80
$ ./script.bash 40 80
40
[4-7][1-9]
80
$ ./script.bash 40 80 | paste -s -d '|'
40|[4-7][1-9]|80
$ ./script.bash 35 55
3[5-9]
[4][0-9]
5[0-5]
您可以使用
paste-s-d'|'
将各个范围合并到单个OR范围中


您可以使用我为3位数字扩展的现有函数(过一段时间后,我也会发布3位版本,其中包含不同的
13
12
)。

只想分享最后的代码::)

函数enc{
a=${1:-3:1};b=${1:-2:1};c=${1:-1}
d=${2:-3:1};e=${2:-2:1};f=${2:-1}
如果($[a]<$[d]);则
如果($b$c==00&$e$f==99));则回显[$a-$d][0-9][0-9]
elif($b$c==00));然后如果($[a+1]<$d));然后echo[$a-$[d-1]][0-9][0-9]“;echo$(enc$[d]00$d$e$f)
else echo$a[0-9][0-9]“|”;echo$(enc$[a+1]00$d$e$f);fi
else echo$(enc$a$b$c$[a]99)“echo$(enc$[a+1]00$d$e$f);fi
elif(($b<$e));然后
如果($c==0&$f==9));则回显$a[$b-$e][0-9]
elif($c==0));然后if($[b+1]<$e));然后echo$a[$b-$[e-1]][0-9]“|”;echo$(enc$a$[e]0$d$e$f)
else echo$a$b[0-9]“|”echo$(enc$a$[e]0$d$e$f);fi
else echo$(enc$a$b$c$a$[b]9)“|”;echo$(enc$a$[b+1]0$d$e$f);fi
其他的
如果(($c==$f));则回显$a$b$c
else echo$a$b[$c-$f];fi;fi
}
函数int{
如果[[$1=*.]];则
整数=${1%.*}
十进制=${1}
如果(${decimal:0:1}>=5));则integer=$[integer+1];fi
echo$integer
else echo$1;fi
}
函数cse{
最小值=$(int$(echo$1$2 | awk'{print($1/$2)*(90)}'))
最大值=$(int$(echo$1$2 | awk'{print($1/$2)*(110)}'))
echo$(enc$最低$最高)
}
cse$1$2
cse
获取两个输入,将它们转换为小数,并从一个范围(即
90
110
中分别乘以-10%和+10%的错误范围),然后将
最小值和
最大值作为输入传递到
enc
,这是一个生成大小写范围语法的递归函数(使用语法优化)


请注意,bash似乎无法按预期或预期处理大小写范围的表达式。不过,此代码可用于为所有2到3位数字生成大小写范围,然后复制并粘贴为内联代码。

如果
语句冗长,则在这种情况下可能更容易获得正确的表达式,并且可读性更强。此外,post文本而不是图像。感谢您的输入。我用可读的代码替换了图像。我知道if语句足够强大,可以处理这个问题,但我认为使用函数作为大小写范围将更加可读和简洁。这段代码中的
$a
是什么,它与“a数字”(Q的第一行)和“两个数字”有什么关系(Q的第二行)?嗨@Kusalananda,
$a
是一个正整数的伪码。我还是不明白。你想看看它是否在某个范围内?你说的“委托”是什么意思?谢谢@南山竹!! 我刚刚从你的脚本中学到了一个新的想法。我正在构建一个用嵌入式case语句设计的结构,而不是ifs和awk,而不是数学的bc。我也在构建快捷方式,例如,
3099
outputs
[3-9][0-9]
而不是
3[0-9]|[4-8][0-9]|9[0-9]
我意识到处理2位和3位数字是我开始所需的全部,因此我可以跳过一位数字。更新了问题以反映对2位和3位数字的解决。上面对此进行了评论,希望与大家分享。好的。我想我能做的是设计两个函数。一个函数最多返回6个输出,因此
12 943
1219 99 899 939 943
,然后一次查看两个输入的第二个函数使用
12 19
生成
1[2-9]
,然后
19 99
生成
19[2-9][0-9]
,等等。使用递归直到没有更多的输入。这应该是更少的代码。我非常喜欢这个答案,分解第一个和最后一个数字,并使用最近的数字。据我所知,非常聪明。感谢您的贡献@ritesht93。@zaydek欢迎:)…你完成了3位数的逻辑构建了吗?我完美地完成了2位数的逻辑构建,但代码太多了。我想我可以用递归从根本上简化它,所以我现在正在研究它。我认为这可能需要10-20行代码。
function enc {

    a=${1: -3:1}; b=${1: -2:1}; c=${1: -1}
    d=${2: -3:1}; e=${2: -2:1}; f=${2: -1}

    if   (( $[a] < $[d] )); then

        if   (( $b$c == 00 && $e$f == 99 )); then echo [$a-$d][0-9][0-9]
        elif (( $b$c == 00 )); then if (( $[a+1] < $d )); then echo [$a-$[d-1]][0-9][0-9] "|"; echo $(enc $[d]00 $d$e$f)
                                                          else echo $a[0-9][0-9] "|"; echo $(enc $[a+1]00 $d$e$f); fi

        else echo $(enc $a$b$c $[a]99) "|"; echo $(enc $[a+1]00 $d$e$f); fi

    elif (( $b < $e )); then

        if   (( $c == 0 && $f == 9 )); then echo $a[$b-$e][0-9]
        elif (( $c == 0 )); then if (( $[b+1] < $e )); then echo $a[$b-$[e-1]][0-9] "|"; echo $(enc $a$[e]0 $d$e$f)
                                                       else echo $a$b[0-9] "|"; echo $(enc $a$[e]0 $d$e$f); fi

        else echo $(enc $a$b$c $a$[b]9) "|"; echo $(enc $a$[b+1]0 $d$e$f); fi

    else

        if (( $c == $f )); then echo $a$b$c
        else echo $a$b[$c-$f]; fi; fi

}

function int {

    if [[ $1 = *.* ]]; then

        integer=${1%.*}
        decimal=${1#*.}

        if (( ${decimal:0:1} >= 5 )); then integer=$[integer+1]; fi

         echo $integer
    else echo $1; fi

}

function cse {

    minimum=$(int $(echo $1 $2 | awk '{ print ($1/$2)*( 90) }'))
    maximum=$(int $(echo $1 $2 | awk '{ print ($1/$2)*(110) }'))

    echo $(enc $minimum $maximum)

}

cse $1 $2