在Linux上将一组文件重命名为001,002 …

我原来有一组图像的formsimage_001.jpg,image_002.jpg,…

我经历了他们,并删除了几个。 现在我想将剩余的文件重命名为image_001.jpg,image_002.jpg,…

有没有一个Linux命令可以做到这一点? 我熟悉重命名,但不能看到任何东西来订购这样的文件名。 我在想,因为ls *.jpg按顺序列出文件(有间隙),解决方法是将输出传递给bash循环或其他东西?

如果我理解正确,你有例如image_001.jpg,image_003.jpg,image_005.jpg,并且你想重命名为image_001.jpg,image_002.jpg,image_003.jpg。

编辑:这是修改为把临时文件在当前目录中。 正如Stephan202指出的那样,如果temp位于不同的文件系统上,这可能会产生显着的差异。 为了避免在循环中击中临时文件,现在通过image *

 i=1; temp=$(mktemp -p .); for file in image* do mv "$file" $temp; mv $temp $(printf "image_%0.3d.jpg" $i) i=$((i + 1)) done 

一个简单的循环(用echo测试,用mv执行):

 I=1 for F in *; do echo "$F" `printf image_%03d.jpg $I` #mv "$F" `printf image_%03d.jpg $I` 2>/dev/null || true I=$((I + 1)) done 

(我添加了2>/dev/null || true来压制关于相同源文件和目标文件的警告,如果这不符合你的要求,请和Matthew Flaschen的回答一起解决 。

尝试以下脚本:

numerate.sh

这段代码应该做的工作:

 ./numerate.sh -d <your image folder> -b <start number> -L 3 -p image_ -s .jpg -o numerically -r 

这与你所要求的相反(把* .jpg.001格式的文件转换成* .001.jpg),但可以很容易地修改你的目的:

 for file in * do if [[ "$file" =~ "(.*)\.([[:alpha:]]+)\.([[:digit:]]{3,})$" ]] then mv "${BASH_REMATCH[0]}" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}.${BASH_REMATCH[2]}" fi done 

这里有一些很好的答案。 但有些依赖于隐藏错误,这不是一个好主意(假设mv只会因为预期的条件而产生错误 – 那么所有其他重复mv可能会错误呢?)。

而且,它可以做得更短一点,应该更好地引用:

 for file in *; do printf -vsequenceImage 'image_%03d.jpg' "$((++i))" [[ -e $sequenceImage ]] || \ mv "$file" "$sequenceImage" done 

另外请注意, 你不应该在bash脚本中大写你的变量 。

我正在使用for循环,一个迭代器,cut -f1 -d“_”,然后mv i.iterator来建议类似上面的内容。 不过,它看起来已经涵盖了其他方法。