【问题标题】:Batch rename sequential files by padding with zeroes通过用零填充来批量重命名顺序文件
【发布时间】:2011-07-22 00:55:01
【问题描述】:

我有一堆像这样命名的文件:

output_1.png
output_2.png
...
output_10.png
...
output_120.png

重命名它们以匹配约定的最简单方法是什么,例如最多四位小数,以便文件命名:

output_0001.png
output_0002.png
...
output_0010.png
output_0120.png

这在 Unix/Linux/BSD 中应该很容易,尽管我也可以访问 Windows。任何语言都可以,但我对一些非常简洁的单行语句感兴趣(如果有的话?)。

【问题讨论】:

标签: batch-file rename batch-rename


【解决方案1】:

Python

import os
path = '/path/to/files/'
for filename in os.listdir(path):
    prefix, num = filename[:-4].split('_')
    num = num.zfill(4)
    new_filename = prefix + "_" + num + ".png"
    os.rename(os.path.join(path, filename), os.path.join(path, new_filename))

您可以编译一个有效文件名列表,假设所有以“output_”开头并以“.png”结尾的文件都是有效文件:

l = [(x, "output" + x[7:-4].zfill(4) + ".png") for x in os.listdir(path) if x.startswith("output_") and x.endswith(".png")]

for oldname, newname in l:
    os.rename(os.path.join(path,oldname), os.path.join(path,newname))

重击

(来自:http://www.walkingrandomly.com/?p=2850

换句话说,我将 file1.png 替换为 file001.png 并将 file20.png 替换为 file020.png 等等。下面是如何在 bash 中做到这一点

#!/bin/bash
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}

将以上内容保存到名为zeropad.sh 的文件中,然后执行以下命令使其可执行

chmod +x ./zeropad.sh

然后您可以按如下方式使用zeropad.sh 脚本

./zeropad.sh frame1.png

返回结果

frame001.png

剩下的就是使用此脚本重命名当前目录中的所有 .png 文件,以便它们被零填充。

for i in *.png;do mv $i `./zeropad.sh $i`; done

Perl

(来自:Zero pad rename e.g. Image (2).jpg -> Image (002).jpg

use strict;
use warnings;
use File::Find;

sub pad_left {
   my $num = shift;

   if ($num < 10) {
      $num = "00$num";
   }
   elsif ($num < 100) {
      $num = "0$num";
   }

   return $num;
}

sub new_name {
   if (/\.jpg$/) {
      my $name = $File::Find::name;
      my $new_name;
      ($new_name = $name) =~ s/^(.+\/[\w ]+\()(\d+)\)/$1 . &pad_left($2) .')'/e;
      rename($name, $new_name);
      print "$name --> $new_name\n";
   }
}

chomp(my $localdir = `pwd`);# invoke the script in the parent-directory of the
                            # image-containing sub-directories

find(\&new_name, $localdir);

重命名

同样来自上面的答案:

rename 's/\d+/sprintf("%04d",$&)/e' *.png

【讨论】:

  • prefix, num = filename[:-4].split('_') 我得到:ValueError: need more than 1 value to unpack
  • 啊,罪魁祸首是它只在目标目录不包含任何其他文件时才有效。它很好,但仍然不是很便携。我会看看其他人是否提出其他解决方案:)
  • 可以访问 Windows。您可以将刚刚发布的 bash 脚本插入到您的答案中,我会接受。只是我喜欢 StackOverflow 的答案已经有代码,而不仅仅是超链接到某个解决方案。
  • 你应该在 bash 脚本中使用printf "%03d" $((10#${num})),否则不接受“08”和“09”。 stackoverflow.com/questions/8078167/…
  • @DTing bash 版本在某些文件不需要重命名时似乎有问题。例如 mv: 'test-100001.txt' and 'test-100001.txt' are the same file 在 mv 没有工作时返回。 (在我的情况下,它已经是 test-%06d.txt)这是否会造成任何问题,或者仅仅是抑制错误消息的问题?
【解决方案2】:

相当简单,尽管它结合了一些不是很明显的功能:

@echo off
setlocal enableextensions enabledelayedexpansion
rem iterate over all PNG files:
for %%f in (*.png) do (
    rem store file name without extension
    set FileName=%%~nf
    rem strip the "output_"
    set FileName=!FileName:output_=!
    rem Add leading zeroes:
    set FileName=000!FileName!
    rem Trim to only four digits, from the end
    set FileName=!FileName:~-4!
    rem Add "output_" and extension again
    set FileName=output_!FileName!%%~xf
    rem Rename the file
    rename "%%f" "!FileName!"
)

编辑:误读您不是在批处理文件,而是在使用任何语言的任何解决方案。对此感到抱歉。为了弥补它,一个 PowerShell 单行:

gci *.png|%{rni $_ ('output_{0:0000}.png' -f +($_.basename-split'_')[1])}

如果您有其他不遵循该模式的文件,请在其中粘贴?{$_.basename-match'_\d+'}

【讨论】:

    【解决方案3】:

    我实际上只需要在 OSX 上执行此操作。这是我为它创建的脚本 - 单行!

    > for i in output_*.png;do mv $i `printf output_%04d.png $(echo $i | sed 's/[^0-9]*//g')`; done
    

    【讨论】:

    • 谢谢。尽管与后缀中包含数字(例如 .mp3)和输入文件名中包含空格的输入文件有关,但我有一些问题。我最好在自己的答案中详细说明,因为 cmets 不允许任何格式。
    【解决方案4】:

    对于大规模重命名,唯一的安全解决方案是mmv——它会检查冲突并允许在链和循环中重命名,这超出了大多数脚本的范围。不幸的是,零填充它并不太热。一种味道:

    c:> mmv output_[0-9].png output_000#1.png
    

    这是一种解决方法:

    c:> type file
    mmv
    [^0-9][0-9] #1\00#2
    [^0-9][0-9][^0-9] #1\00#2#3
    [^0-9][0-9][0-9] #1\0#2#3
    [^0-9][0-9][0-9][^0-9] #1\0#2#3
    c:> mmv <file
    

    【讨论】:

      【解决方案5】:

      Here 是我编写的 Python 脚本,它根据存在的最大数字填充零,并忽略给定目录中的非编号文件。用法:

      python ensure_zero_padding_in_numbering_of_files.py /path/to/directory
      

      脚本正文:

      import argparse
      import os
      import re
      import sys
      
      def main(cmdline):
      
          parser = argparse.ArgumentParser(
              description='Ensure zero padding in numbering of files.')
          parser.add_argument('path', type=str,
              help='path to the directory containing the files')
          args = parser.parse_args()
          path = args.path
      
          numbered = re.compile(r'(.*?)(\d+)\.(.*)')
      
          numbered_fnames = [fname for fname in os.listdir(path)
                             if numbered.search(fname)]
      
          max_digits = max(len(numbered.search(fname).group(2))
                           for fname in numbered_fnames)
      
          for fname in numbered_fnames:
              _, prefix, num, ext, _  = numbered.split(fname, maxsplit=1)
              num = num.zfill(max_digits)
              new_fname = "{}{}.{}".format(prefix, num, ext)
              if fname != new_fname:
                  os.rename(os.path.join(path, fname), os.path.join(path, new_fname))
                  print "Renamed {} to {}".format(fname, new_fname)
              else:
                  print "{} seems fine".format(fname)
      
      if __name__ == "__main__":
          sys.exit(main(sys.argv[1:]))
      

      【讨论】:

        【解决方案6】:
        $rename output_ output_0 output_?   # adding 1 zero to names ended in 1 digit
        $rename output_ output_0 output_??  # adding 1 zero to names ended in 2 digits
        $rename output_ output_0 output_??? # adding 1 zero to names ended in 3 digits
        

        就是这样!

        【讨论】:

          【解决方案7】:

          我正在关注 Adam 的 OSX 解决方案。

          我在场景中遇到的一些问题是:

          1. 我有一组 .mp3 文件,因此 sed 捕获了“.mp3”后缀中的“3”。 (我使用 basename 而不是 echo 来纠正这个问题)
          2. 我的 .mp3 名称中有空格,例如,“audio track 1.mp3”,这导致 basename+sed 有点搞砸了,所以我不得不引用“$ i”参数。

          最后,我的转换线是这样的:

          for i in *.mp3 ; do mv "$i" `printf "track_%02d.mp3\n" $(basename "$i" .mp3 | sed 's/[^0-9]*//g')` ; done
          

          【讨论】:

            【解决方案8】:

            使用ls + awk + sh

            ls -1 | awk -F_ '{printf "%s%04d.png\n", "mv "$0" "$1"_", $2}' | sh
            

            如果您想在运行之前测试该命令,只需删除 | sh

            【讨论】:

              【解决方案9】:

              使用 bash 拆分,

              Linux

              for f in *.png;do n=${f#*_};n=${n%.*};mv $f $(printf output_"%04d".png $n);done
              

              windows(bash)

              for f in *.png;do n=${f#*_};mv $f $(printf output_"%08s" $n);done
              

              【讨论】:

                【解决方案10】:

                我只想制作延时电影

                ffmpeg  -pattern_type glob -i "*.jpg" -s:v 1920x1080 -c:v libx264 output.mp4 
                

                遇到了类似的问题。

                [image2 @ 000000000039c300] 选择了模式类型“glob”,但此 libavformat 构建不支持通配

                glob 在 Windows 7 上不支持。 此外,如果文件列表如下所示,并使用 %2d.jpg 或 %02d.jpg

                1.jpg 2.jpg ... 10.jpg 11.jpg ...

                [image2 @ 00000000005ea9c0] Could find no file with path '%2d.jpg' and index in the range 0-4  
                %2d.jpg: No such file or directory 
                [image2 @ 00000000005aa980] Could find no file with path '%02d.jpg' and index in the range 0-4  
                %02d.jpg: No such file or directory
                

                这是我重命名苍蝇的批处理脚本

                @echo off
                setlocal enabledelayedexpansion
                
                set i=1000000
                set X=1
                for %%a in (*.jpg) do (
                    set /a i+=1
                    set "filename=!i:~%X%!"
                    echo ren "%%a" "!filename!%%~xa"
                    ren "%%a" "!filename!%%~xa"
                )
                

                重命名 143,323 个 jpg 文件后,

                ffmpeg -i %6d.jpg -s:v 1920x1080 -c:v libx264 output.mp4 
                

                【讨论】:

                  猜你喜欢
                  • 2014-04-22
                  • 2017-01-01
                  • 1970-01-01
                  • 2014-07-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-27
                  • 2019-04-08
                  • 2021-05-12
                  相关资源
                  最近更新 更多