20

我最初有一组图像,格式为 image_001.jpg、image_002.jpg、...

我浏览了它们并删除了几个。现在我想将剩余文件重命名为 image_001.jpg、image_002.jpg、...

是否有一个 Linux 命令可以巧妙地做到这一点?我对重命名很熟悉,但看不到任何可以像这样订购文件名的东西。我在想,由于ls *.jpg按顺序列出文件(有间隙),解决方案是将其输出传递到 bash 循环或其他东西中?

4

6 回答 6

14

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

编辑:修改为将临时文件放在当前目录中。正如 Stephan202 所指出的,如果 temp 位于不同的文件系统上,这可能会产生重大影响。为了避免在循环中碰到临时文件,它现在通过图像*

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                                      
于 2009-05-19T00:47:32.240 回答
9

一个简单的循环(用 测试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回答。)

于 2009-05-19T00:46:43.037 回答
2

尝试以下脚本:

计算.sh

这段代码剪断应该可以完成这项工作:

./numerate.sh -d <your image folder> -b <start number> -L 3 -p image_ -s .jpg -o numerically -r
于 2014-09-23T20:07:55.103 回答
1

这与您所要求的相反(获取格式为 *.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
于 2009-05-19T00:43:52.577 回答
1

这里已经有一些很好的答案;但有些人依赖隐藏错误,这不是一个好主意(假设mv只会因为预期的条件而出错 - 所有其他原因mv可能会出错呢?)。

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

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

另请注意,您不应在 bash 脚本中将变量大写。

于 2009-05-19T06:28:36.920 回答
0

我打算使用 for 循环、迭代器、cut -f1 -d "_" 和 mv i i.iterator 来建议类似上面的内容。不过,看起来它已经涵盖了其他方式。

于 2009-05-19T00:49:21.580 回答