【问题标题】:How to rename sequential files so they start from zero?如何重命名顺序文件以使它们从零开始?
【发布时间】:2012-02-21 09:23:30
【问题描述】:

一种不优雅、不灵活的做法是这样的:

for path in *.jpg # IMG_1067_CR2.jpg, MG_1068_CR2.jpg, etc.
do
    mv "$path" "${index-0}.jpg"
    let index+=1
done
unset index

一个更好的方法应该支持前导零(例如ffmpeg),避免使用虚拟变量污染环境,有一个空运行选项(例如rename),并且不应该要求指定两次扩展。现有工具是否支持此功能?

或者,我怎样才能让this solution 使用前导零:

rename -n 's/IMG_([0-9]*)\.jpg/$1/; $_="IMG_".($_-1067).".jpg"' *.jpg 

【问题讨论】:

    标签: bash rename


    【解决方案1】:

    你可以这样做:

    rename -n 's/IMG_([0-9]*)\.jpg/$1/; $_="IMG_".substr("000" . ($_-1067), -4).".jpg"' *.jpg
    

    这会将“0”渲染为“0000”,将“907”渲染为“0907”。

    【讨论】:

    • @l0b0:不是sed,是Perl。
    • @shil88:区别似乎是 OP 的文件从 1067 开始,而你的文件不是。这不是不工作的问题,而是简单地容纳一组不同的数据。顺便说一句,您可以省略 +0 和周围的括号。
    • 非常感谢您的澄清!现在我理解了命令,并且出于某种疯狂的原因,您的解决方案“按原样”完美运行。 (当时它“显然”显示出一种随机行为……这对我来说肯定很奇怪!)。我将删除我之前的评论并保留它。
    【解决方案2】:

    这会将IMG_1067_CR2.jpg, IMG_1068_CR2.jpg... 变成IMG_0_CR2.jpg, IMG_1_CR2.jpg ...。如果您对结果满意,请删除echo

    #!/bin/bash
    i=0
    for img in *.jpg; do
      echo mv "$img" "${img/_[[:digit:]]*_/_$((i++))_}"
    done
    unset i
    

    如果您希望更改递归到多个级别的子目录。通过执行以下操作,您可以使用 Bash 4.x 轻松完成此操作:

    1. 在 for 循环之前添加以下行:shopt -s globstar
    2. for img in *.jpg; do 更改为for img in **/*.jpg; do

    【讨论】:

    • 我相信local 不能在函数之外使用。
    【解决方案3】:

    要处理前导零,可以使用printf

    ...
    NEW=$(printf "%04d.jpg" $index)
    mv "$path" "$NEW"
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-16
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 2016-10-08
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多