从我们在评论中进行的所有有趣的讨论(那是一个非常有趣的话题),我或多或少(可能不太了解)你想要什么......或者更确切地说,我对我相信你想要什么有了自己的想法。让我重新表述一下我的理解(如果这不是您的确切要求,请原谅我)。
您需要一个脚本,该脚本将采用三个非负数字参数X
,Y
并且Z
(可能带有前导0
),X<Y
并且您希望输出test-M => test-N
其中:
M
范围从X
到,用'sY
左填充,因此其中的字符数是和中的最大字符数0
M
X
Y
N=M+Z
, 用 's 向左填充,0
这样字符数就是,和的N
最大字符数。例如,X
Y
Z
Y+Z
$ ./script 01 04 00220
test-01 => test-00221
test-02 => test-00222
test-03 => test-00223
test-04 => test-00224
$ ./script 99 101 0
test-099 => test-099
test-100 => test-100
test-101 => test-101
$ ./script 99 101 00000
test-099 => test-00099
test-100 => test-00100
test-101 => test-00101
$ ./script 00 02 99
test-00 => test-099
test-01 => test-100
test-02 => test-101
此外,您需要一个 bash 解决方案,这样您就可以mv
在不需要解析另一个命令的输出的情况下获取相应的文件。
我们开始吧,希望你也能找到一些有趣的东西来挖掘(注意,输出是表单mv -nv xxx yyy
而不是;当你对此感到满意时test-x => test-y
删除):echo
#!/bin/bash
prepend_source=test-
prepend_target=test-
append_source=
append_target=
shopt -s extglob
die() { printf >&2 "%s\n" "$@"; exit 1; }
is_number() { [[ $1 = +([[:digit:]]) ]]; }
is_in_range() { [[ -z ${1//0/} ]] || [[ ${1/#+(0)} = $((10#$1)) ]]; }
maxlength() {
local u l=0 retvar=$1
shift
for i in "$@"; do
u=${#i}
((u>l)) && ((l=u))
done
printf -v "$retvar" "%d" "$l"
}
X=$1
Y=$2
Z=$3
is_number "$X" || die "First argument is not a valid number"
is_number "$Y" || die "Second argument is not a valid number"
is_number "$Z" || die "Third argument is not a valid number"
(( 10#$X <= 10#$Y )) || die "Error: first argument is greater than second"
is_in_range "$X" || die "First argument out of range"
is_in_range "$Y" || die "Second argument out of range"
is_in_range "$Z" || die "Third argument out of range"
(( 10#$Y + 10#$Z >= 0 )) || die "Sum of second and last arguments is out of range"
maxlength "length_s" "$X" "$Y"
maxlength "length_t" "$X" "$Y" "$Z" "$((10#$Y+10#$Z))"
for ((i=10#$X;i<=10#$Y;++i)); do
printf -v source "%s%.${length_s}d%s" "$prepend_source" "$i" "$append_source"
printf -v target "%s%.${length_t}d%s" "$prepend_target" "$((10#$Z+$i))" "$append_target"
# Here we're all done!
echo mv -nv -- "$source" "$target" || die "Problem in mv" # or another error handle
done
我在脚本的开头添加了变量prepend_source
, append_source
, prepend_target
,append_target
以便您可以轻松地将它们替换为您想要的。您可以添加选项解析以便能够从命令行设置它们(留作练习,除非您坚持我为您做)。
警告。这些数字由 bash 直接处理,因此您必须在 bash 的算术范围内使用它们,这(很可能)在 64 位机器上:[-9223372036854775808,9223372036854775807]。所以在达到这个目标之前你可以做很多事情。现在,不用担心,如果超出此范围,脚本不会中断,因为我添加了显式检查。如果这确实是一个限制,您始终可以使用bc
ordc
代替。bc
ordc
实现留给读者作为练习。顺便说一句,这只适用于非负整数。
您的解决方案是否像这个一样强大和通用?