我正在尝试将文件夹从1移动到05并为其分配数字。
示例:
test-01 => test-221
test-02 => test-222
test-03 => test-223
test-04 => test-224
test-05 => test-225
我试过了;
for num in $(seq -w $2 $3); {
mv -v "test-$num" "test-$1$num"
}
像这样使用它;
./script.sh 2 21 25
但我得到了输出;
test-21 => test-221
test-22 => test-222
test-23 => test-223
test-24 => test-224
test-25 => test-225
这当然是错误的,参见示例: - )
我也是这样试过的;
for a in {1..5}; {
for b in {21..25}; {
echo "$a => $b"
} #b
} #a
但我会像这样重复输出;
1 => 21
1 => 22
1 => 23
1 => 24
1 => 25
2 => 21
2 => 22
2 => 23
2 => 24
2 => 25
3 => 21
3 => 22
3 => 23
3 => 24
3 => 25
4 => 21
4 => 22
4 => 23
4 => 24
4 => 25
5 => 21
5 => 22
5 => 23
5 => 24
5 => 25
答案 0 :(得分:2)
尝试使用awk
#!/bin/bash
awk -v fa=$1 -v fb=$2 -v ta=$3 'BEGIN { for(i=fa;i<=fb;i++) printf "test-%02d => test-%02d\n",i,i+ta }'
测试
$bash -f main.sh 1 5 220
test-01 => test-221
test-02 => test-222
test-03 => test-223
test-04 => test-224
test-05 => test-225
在OP的请求上看起来很漂亮的多行代码
#!/bin/bash
awk -v fa=$1 -v fb=$2 -v ta=$3 'BEGIN {
for(i=fa;i<=fb;i++)
printf "test-%02d => test-%02d\n",i,i+ta
}'
现在用于移动文件的实际脚本
#!/bin/bash
awk -v fa=$1 -v fb=$2 -v ta=$3 'BEGIN {
for(i=fa;i<=fb;i++) {
cmd = sprintf ("mv -v test-%02d test-%02d",i ,i+ta);
# print cmd;
system(cmd);
}
}'
答案 1 :(得分:1)
from_a=1
to_a=5
width_a=2
from_b=220
width_b=3
for a in $(seq $from_a $to_a); do
printf -v file_a "%0"$width_a"d" "$a"
printf -v file_b "%0"$width_b"d" $(($a + $from_b))
echo "test-$file_a => test-$file_b"
done
答案 2 :(得分:1)
从我们在评论中提到的所有有趣的讨论(这是一个非常有趣的主题),我或多或少(可能少)理解你想要的东西......或者说,我做了我的我自己的想法,我相信你想要的。让我重新理解我理解的内容(如果这不是你要求的话,请原谅我。)
你想要一个脚本,它会带有三个非负数字参数X
,Y
和Z
(可能带领0
)和{{1}并且您想要输出X<Y
其中:
test-M => test-N
的范围从M
到X
,左边填充Y
,以便0
中的字符数是最大数量M
和X
Y
,左侧填充N=M+Z
个,以便0
中的字符数是N
的最大字符数,{{ 1}},X
和Y
。如,
Z
此外,您需要一个bash解决方案,以便您可以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
而不是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
,以便您可以根据需要轻松替换它们。你可以添加选项解析,以便能够从命令行设置它们(左边作为练习,除非你坚持我为你做这个)。
<强>买者强>的数字直接由bash的64位机器上处理的,所以必须从它是(很可能)bash的算术范围内使用它们。所以在达到目标之前你可以做很多事情。现在,不要担心,如果超出此范围,脚本将不会中断,因为我添加了显式检查。如果这确实是一个限制,您可以随时使用prepend_target
或append_target
。 bc
或dc
实施作为练习留给读者。顺便说一句,这只适用于非负整数。
您的解决方案是否与此一样强大且通用?
答案 3 :(得分:0)
你只需要一个循环。但无论你怎么计算它,你用于一个目的的数字对于另一个目的而言将是错误的数字。因此,您需要使用算术来获得正确的数字,例如:
$(( $num + 220 ))
答案 4 :(得分:0)
这是我到目前为止所拥有的;
for i in $(seq -w $1 $2); {
echo "test-$i => test-$((i+$3))"
} #for
输出我通过运行./script.sh 01 05 220
test-01 => test-221
test-02 => test-222
test-03 => test-223
test-04 => test-224
test-05 => test-225
所以看起来它符合我的例子: - )
答案 5 :(得分:0)
感谢所有人的帮助,这就是我现在所拥有的;
for i in $(seq -w $1 $2); {
echo "test-$i => test-$((10#$i+$3))"
} #for
这是我运行时获得的输出./script.sh 01 10 220例如;
test-01 => test-221
test-02 => test-222
test-03 => test-223
test-04 => test-224
test-05 => test-225
test-06 => test-226
test-07 => test-227
test-08 => test-228
test-09 => test-229
test-10 => test-230
这正是我想要实现的目标。非常感谢“Robin Green”和“gniourf_gniourf”。
现在移动目录正常工作^ _ ^
mv -v "temp/test-$i" "temp/test-$((10#$i+$3))"
移动目录的输出是;
‘temp/test-01’ -> ‘temp/test-221’
‘temp/test-02’ -> ‘temp/test-222’
‘temp/test-03’ -> ‘temp/test-223’
‘temp/test-04’ -> ‘temp/test-224’
‘temp/test-05’ -> ‘temp/test-225’
‘temp/test-06’ -> ‘temp/test-226’
‘temp/test-07’ -> ‘temp/test-227’
‘temp/test-08’ -> ‘temp/test-228’
‘temp/test-09’ -> ‘temp/test-229’
‘temp/test-10’ -> ‘temp/test-230’
问题只发生在我跑步时; ./script.sh 01 10 0这是我得到的输出;
test-01 => test-1
test-02 => test-2
test-03 => test-3
test-04 => test-4
test-05 => test-5
test-06 => test-6
test-07 => test-7
test-08 => test-8
test-09 => test-9
test-10 => test-10
因为你看不到前导零=(