我有一些文件名为:
0001.jpg
0002.jpg
...
0050.jpg
我需要将该数字增加 35,以便获得:
0036.jpg
0037.jpg
...
0085.jpg
我想尝试以下方法:
for i in {0001..0050}; do
mv -n $i $((i+35))
done
但是我收到错误bash: 0008: value too great for base (error token is "0008")
. 我不确定我是否理解base
在这里的含义或如何绕过它。 我见过这个问题。 虽然它解释了八进制误差,但目前还不清楚它如何帮助迭代移位索引。
最终我选择了:
for i in {50..1};
do
old=$(printf '%04d.jpg' $i)
new=$(printf '%04d.jpg' $((i + 34)))
mv -i -- "$old" "$new" #-i to avoid overwritting
done
bash,像C一样,在算术展开中使用时,将以零开头的数字解释为八进制数。 这是 POSIX sh 的标准行为。 由于"8"不是八进制数中的有效值,因此会出现错误。
由于您想要从 1 数到 50 并加 35,然后将其格式化为数字,因此您可以执行以下操作:
#!/bin/sh
for i in $(seq 50 -1 1)
do
mv -n $(printf '%04d.jpg' $i) $(printf '%04d.jpg' $((i + 35)))
done
这将从 50 迭代到 1,并使用printf
程序格式化每个数字。 顺便说一下,除了在 bash 中工作之外,这也是便携式 POSIX sh。
问题是 bash 算术将以0
开头的数字视为八进制数,八进制系统中只允许 0-7 位数字。您可以在数字之前加上前缀10#
以告诉 bash 接受给定的数字作为基数 10 并计算您的总和。
您可以使用:
for i in {0010..0001}.jpg; do
f="${i%.jpg}"
echo mv "$i $(printf '%04d' $((10#$f + 10#35))).jog"
done
对输出感到满意后,请在mv
之前删除echo
。
mv 0010.jpg 0045.jog
mv 0009.jpg 0044.jog
mv 0008.jpg 0043.jog
mv 0007.jpg 0042.jog
mv 0006.jpg 0041.jog
mv 0005.jpg 0040.jog
mv 0004.jpg 0039.jog
mv 0003.jpg 0038.jog
mv 0002.jpg 0037.jog
mv 0001.jpg 0036.jog
几乎@Massagran您自己的解决方案:
#!/usr/bin/env bash
for i in {50..1}; do
printf -v old_filename '%04d.jpg' $i
printf -v new_filename '%04d.jpg' $((i + 35))
[[ -f $old_filename ]] && mv --no-clobber -- "$old_filename" "$new_filename"
done
它有何不同并改善您的答案:
它不是通过在子 shell 中运行
printf
来捕获printf
的输出到变量中,而是使用-v
选项,因此printf
输出直接到变量中。在执行重命名之前,它会测试旧文件名是否存在并且是实际文件。
为了防止覆盖现有文件,它使用
--no-clobber
而不是--interactive
选项。