在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