【问题标题】:Renaming a set of files to 001, 002,在 Linux 上将一组文件重命名为 001、002、...
【发布时间】:2010-10-27 04:46:30
【问题描述】:

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

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

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

【问题讨论】:

    标签: linux bash shell file rename


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      一个简单的循环(用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 Flaschenanswer。)

      【讨论】:

      • 这不起作用。大多数图像仍将保留其原始名称,因此 mv 将失败。
      • @Matthew:好地方。现在更改代码,以便将所有文件移动到临时目录。
      • 明确地说,它适用于其他图像,但会产生可能破坏的虚假错误,例如生成文件。
      • @Matthew:再想想,失败不是问题。我将还原代码。
      • 请记住,即使使用 /dev/null,mv 也会失败,因此 make(和类似的)仍然会中断。
      【解决方案3】:

      如果我理解正确,您有例如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                                      
      

      【讨论】:

      • 不错(只要 mktemp 在同一个卷上创建文件,否则移动到临时子目录会更快)
      • 我将把它标记为答案,但我不需要使用临时目录:我的图像实际上从 002 开始(有间隙),因此不会有任何冲突. 002 更名为 001、005->002、006->003 以此类推。
      • 供其他人参考,我最后的命令是:i=0;对于 *.jpg 中的文件;做 mv "$file" $(printf "image_%0.3d.jpg" $i); i=$((i+1));完成
      【解决方案4】:

      我打算使用一个 for 循环、一个迭代器、cut -f1 -d "_",然后是 mv i i.iterator 来建议类似上面的东西。不过,它似乎已经涵盖了其他方式。

      【讨论】:

        【解决方案5】:

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

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

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

        还要注意 bash 脚本中的 you shouldn't capitalize your variables

        【讨论】:

        • 使用最新版本的 bash,您可以使用:printf -vsequenceImage 'image_%03d.jpg' $((++i))
        • 实际上,您是在子外壳中操作 i 变量,因此在您的示例中它不会增加。
        • radoulov:很好看,谢谢。我认为我应该测试我写的东西。
        【解决方案6】:

        试试下面的脚本:

        numerate.sh

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-01
          • 2013-12-13
          • 2018-12-11
          • 1970-01-01
          • 1970-01-01
          • 2015-12-13
          • 2023-03-03
          • 2018-10-26
          相关资源
          最近更新 更多