如何在bash中移动数字?

如何在bash中移动数字?,bash,Bash,我有一个家庭作业,要求将一个十进制数移位指定的位数。更清楚的是,这个bash脚本将接受两个输入参数,第一个是执行移位的位数(最多9位),第二个是要移位的位数(-9到9)。另一个要求是,当一个数字从一端移开时,它应该附加到数字的另一端。一个令人头痛的需求是,我们不能使用任何类型的控制语句:没有循环、没有if和switch情况 示例:123453应为345000012,12345-3应为12345000 我知道如果我把12345除以10^3,我得到345,如果我把12345除以10^3,我得到12,

我有一个家庭作业,要求将一个十进制数移位指定的位数。更清楚的是,这个bash脚本将接受两个输入参数,第一个是执行移位的位数(最多9位),第二个是要移位的位数(-9到9)。另一个要求是,当一个数字从一端移开时,它应该附加到数字的另一端。一个令人头痛的需求是,我们不能使用任何类型的控制语句:没有循环、没有if和switch情况

示例:123453应为345000012,12345-3应为12345000

我知道如果我把12345除以10^3,我得到345,如果我把12345除以10^3,我得到12,然后我可以把这两个变量连在一起,得到34512。我不确定这是否完全正确,但这是我目前能得到的最接近的结果。至于-3移位,我知道10^-3是.001,但是当我尝试在bash中使用10^-3时,会出现一个错误

我只是在这一点上迷路了,任何提示都将不胜感激

编辑:经过几个小时的抨击(双关语的意思)我的头对这个问题,我终于想出了一个脚本,大部分工作。我想现在就发布代码,但我担心另一个迷路的学生可能会偶然发现它。我会在一两周内回来看看并发布我的想法。我可以用mods和division来完成。谢谢大家的回复,这真的帮助我敞开心扉,从不同的角度思考这个问题

这里有一个提示:

echo ${string:0:3}
echo ${#string}
编辑(2011-02-11):

这是我的解决办法。我添加了一些带有默认值的附加参数

rotate-string ()
{
    local s=${1:-1} p=${2:--1} w=${3:-8} c=${4:-0} r l
    printf -vr '%0*d' $w 0    # save $w zeros in $r
    r=${r//0/$c}$s            # change the zeros to the character in $c, append the string
    r=${r: -w}                # save the last $w characters of $r
    l=${r: -p%w}              # get the last part of $r ($p mod %w characters)
    echo "$l${r::w-${#l}}"    # output the Last part on the Left and the Right part which starts at the beginning and goes for ($w minus the_length_of_the_Left_part) characters
}
用法:
旋转字符串位置以旋转宽度填充字符

示例:
旋转字符串abc-4 9=

结果:
==abc===

可以从末尾开始省略参数,将使用以下默认值:

  • 填充字符:“0”
  • 宽度:8
  • 要旋转的位置:-1
  • 字符串:“1”
更多示例:

$ rotate-string
00000010
$ rotate-string 123 4
01230000
有趣的东西:

$ for i in {126..6}; do printf '%s\r' "$(rotate-string Dennis $i 20 .)"; sleep .05; done; printf '\n'

$ while true; do for i in {10..1} {1..10}; do printf '%s\r' "$(rotate-string : $i 10 .)"; sleep .1; done; done

$ while true; do for i in {40..2} {2..40}; do printf '%s\r' "$(rotate-string '/\' $i 40 '_')"; sleep .02; done; done

$ d=0; while true; do for i in {1..10} {10..1}; do printf '%s\r' "$(rotate-string $d $i 10 '_')"; sleep .02; done; ((d=++d%10)); done

$ d=0; while true; do for i in {1..10}; do printf '%s\r' "$(rotate-string $d $i 10 '_')"; sleep .2; ((d=++d%10)); done; done

$ shape='▁▂▃▄▅▆▇█▇▆▅▄▃▂▁'; while true; do for ((i=1; i<=COLUMNS; i++)); do printf '%s\r' "$(rotate-string "$shape" $i $COLUMNS ' ')"; done; done
{126..6}中i的
$;执行printf'%s\r'$(旋转字符串Dennis$i 20.)”;睡眠。05;完成;printf'\n'
$虽然正确;在{10..1}{1..10}中为我做;执行printf'%s\r'$(旋转字符串:$i10。)”;睡眠:1;完成;完成
$虽然正确;在{40..2}{2..40}中为我做;是否打印“%s\r'$(旋转字符串“/\'$i 40'”;睡眠。02;完成;完成
$d=0;虽然真实;在{1..10}{10..1}中为我做;不打印“%s\r'$(旋转字符串$d$i 10'”;睡眠。02;完成;(d=++d%10));完成
$d=0;虽然真实;在{1..10}中为我做;不打印“%s\r'$(旋转字符串$d$i 10'”;睡眠;(d=++d%10));完成;完成

$shape='1▁▂▃▄▅▆▇█▇▆▅▄▃▂▁'; 虽然真实;do for((i=1;i在没有控制结构的情况下,您需要使用递归,将索引值作为“选择”,这就是函数式编程通常的工作方式

#!/bin/sh
#
# cshift NUMBER N
cshift() {
  let num=10#$1
  num=`printf '%09d' $num`
  lshift="${num:1:8}${num:0:1}"
  rshift="${num:8:1}${num:0:8}"
  next=( "cshift $lshift $(($2 + 1))" "echo $num" "cshift $rshift $(( $2 - 1 ))" )
  x=$(( $2 == 0 ? 1 : $2 < 0 ? 0 : 2 ))
  eval "${next[x]}"
}

cshift $1 $2
!/bin/sh
#
#换档编号N
cshift(){
设num=10#$1
num=`printf'%09d'$num`
lshift=“${num:1:8}${num:0:1}”
rshift=“${num:8:1}${num:0:8}”
下一步=(($2+1))“$echo$num”“cshift$rshift$($2-1))”)
x=$($2==0-1:$2<0-0:2))
评估“${next[x]}”
}
cshift$1$2
以及测试:

$ for ((i=-9;i<=9;i++)); do cshift 12345 $i ; done
000012345
500001234
450000123
345000012
234500001
123450000
012345000
001234500
000123450
000012345
500001234
450000123
345000012
234500001
123450000
012345000
001234500
000123450
000012345

$for((i=-9;i这里有一个提示,也许这会让你朝着正确的方向前进:不要把这看作一个数学问题。把它看作一个字符串处理问题,有9个一个字符的字符串。搜索rotate strings你允许调用吗?没有什么说我们不能…这里有另一个提示,因为它可能不是直观的:
echo${string:-1:1}
echo${string:(-1:1}
但不是
echo${string:-1:1}
可以认为条件(三元)运算符是一种控制语句。您有
#!/bin/sh
,但它应该是
#!/bin/bash
,因为至少在许多系统上,
sh
至少没有您正在使用的一些功能。我可以在一个103字符的函数中完成这项工作,而无需递归、控制语句(或条件运算符)或
eval