【问题标题】:Batch Renaming of Files in a Directory批量重命名目录中的文件
【发布时间】:2010-09-18 13:14:16
【问题描述】:

有没有一种简单的方法可以使用 Python 重命名目录中已包含的一组文件?

示例:我有一个充满 *.doc 文件的目录,我想以一致的方式重命名它们。

X.doc -> “新(X).doc”

Y.doc -> "new(Y).doc"

【问题讨论】:

    标签: python file-io rename batch-rename


    【解决方案1】:

    以 Cesar Canassa comment 以上为基础。

    import os
    [os.rename(f, f.replace(f[f.find('___'):], '')) for f in os.listdir('.') if not f.startswith('.')]
    

    这将找到三个下划线 (_) 并将它们以及它们后面的所有内容替换为空 ('')。

    【讨论】:

      【解决方案2】:

      如果您想在编辑器(例如 vim)中修改文件名,click 库带有命令 click.edit(),可用于接收来自编辑器的用户输入。这是一个如何使用它来重构目录中的文件的示例。

      import click
      from pathlib import Path
      
      # current directory
      direc_to_refactor = Path(".")
      
      # list of old file paths
      old_paths = list(direc_to_refactor.iterdir())
      
      # list of old file names
      old_names = [str(p.name) for p in old_paths]
      
      # modify old file names in an editor,
      # and store them in a list of new file names
      new_names = click.edit("\n".join(old_names)).split("\n")
      
      # refactor the old file names
      for i in range(len(old_paths)):
          old_paths[i].replace(direc_to_refactor / new_names[i])
      

      我编写了一个命令行应用程序,它使用相同的技术,但减少了该脚本的波动性,并提供了更多选项,例如递归重构。这是github page 的链接。如果您喜欢命令行应用程序,并且有兴趣对文件名进行一些快速编辑,这将非常有用。 (我的应用类似于ranger 中的“bulkrename”命令)。

      【讨论】:

      • 虽然我们鼓励链接到外部资源,但我们不鼓励仅链接的答案,因为当链接过期时它们会变得无用。请更新您的回复以包含问题的答案:)
      • 当然。我将编辑我的帖子。这是我的第一个贡献,非常感谢您的指导!
      【解决方案3】:

      此代码将起作用

      该函数将两个参数 f_patth 作为重命名文件的路径,并将 new_name 作为文件的新名称。

      import glob2
      import os
      
      
      def rename(f_path, new_name):
          filelist = glob2.glob(f_path + "*.ma")
          count = 0
          for file in filelist:
              print("File Count : ", count)
              filename = os.path.split(file)
              print(filename)
              new_filename = f_path + new_name + str(count + 1) + ".ma"
              os.rename(f_path+filename[1], new_filename)
              print(new_filename)
              count = count + 1
      

      【讨论】:

        【解决方案4】:

        位于您需要执行重命名的目录中。

        import os
        # get the file name list to nameList
        nameList = os.listdir() 
        #loop through the name and rename
        for fileName in nameList:
            rename=fileName[15:28]
            os.rename(fileName,rename)
        #example:
        #input fileName bulk like :20180707131932_IMG_4304.JPG
        #output renamed bulk like :IMG_4304.JPG
        

        【讨论】:

        • 要“在目录中...”使用os.chdir(path_of_directory)
        【解决方案5】:
        #  another regex version
        #  usage example:
        #  replacing an underscore in the filename with today's date
        #  rename_files('..\\output', '(.*)(_)(.*\.CSV)', '\g<1>_20180402_\g<3>')
        def rename_files(path, pattern, replacement):
            for filename in os.listdir(path):
                if re.search(pattern, filename):
                    new_filename = re.sub(pattern, replacement, filename)
                    new_fullname = os.path.join(path, new_filename)
                    old_fullname = os.path.join(path, filename)
                    os.rename(old_fullname, new_fullname)
                    print('Renamed: ' + old_fullname + ' to ' + new_fullname
        

        【讨论】:

          【解决方案6】:

          我遇到了类似的问题,但我想将文本附加到目录中所有文件的文件名开头,并使用了类似的方法。请参见下面的示例:

          folder = r"R:\mystuff\GIS_Projects\Website\2017\PDF"
          
          import os
          
          
          for root, dirs, filenames in os.walk(folder):
          
          
          for filename in filenames:  
              fullpath = os.path.join(root, filename)  
              filename_split = os.path.splitext(filename) # filename will be filename_split[0] and extension will be filename_split[1])
              print fullpath
              print filename_split[0]
              print filename_split[1]
              os.rename(os.path.join(root, filename), os.path.join(root, "NewText_2017_" + filename_split[0] + filename_split[1]))
          

          【讨论】:

            【解决方案7】:

            至于我在我的目录中我有多个子目录,每个子目录都有很多图像我想将所有子目录图像更改为 1.jpg ~ n.jpg

            def batch_rename():
                base_dir = 'F:/ad_samples/test_samples/'
                sub_dir_list = glob.glob(base_dir + '*')
                # print sub_dir_list # like that ['F:/dir1', 'F:/dir2']
                for dir_item in sub_dir_list:
                    files = glob.glob(dir_item + '/*.jpg')
                    i = 0
                    for f in files:
                        os.rename(f, os.path.join(dir_item, str(i) + '.jpg'))
                        i += 1
            

            (我自己的回答)https://stackoverflow.com/a/45734381/6329006

            【讨论】:

              【解决方案8】:
              directoryName = "Photographs"
              filePath = os.path.abspath(directoryName)
              filePathWithSlash = filePath + "\\"
              
              for counter, filename in enumerate(os.listdir(directoryName)):
              
                  filenameWithPath = os.path.join(filePathWithSlash, filename)
              
                  os.rename(filenameWithPath, filenameWithPath.replace(filename,"DSC_" + \
                        str(counter).zfill(4) + ".jpg" ))
              
              # e.g. filename = "photo1.jpg", directory = "c:\users\Photographs"        
              # The string.replace call swaps in the new filename into 
              # the current filename within the filenameWitPath string. Which    
              # is then used by os.rename to rename the file in place, using the  
              # current (unmodified) filenameWithPath.
              
              # os.listdir delivers the filename(s) from the directory
              # however in attempting to "rename" the file using os 
              # a specific location of the file to be renamed is required.
              
              # this code is from Windows 
              

              【讨论】:

                【解决方案9】:

                我有这个简单地重命名文件夹子文件夹中的所有文件

                import os
                
                def replace(fpath, old_str, new_str):
                    for path, subdirs, files in os.walk(fpath):
                        for name in files:
                            if(old_str.lower() in name.lower()):
                                os.rename(os.path.join(path,name), os.path.join(path,
                                                            name.lower().replace(old_str,new_str)))
                

                我将所有出现的 old_str 替换为 new_str。

                【讨论】:

                • 这段代码实际上是用来替换目录中文件标题的任何部分。
                【解决方案10】:

                我自己编写了一个 python 脚本。它将文件所在目录的路径和您要使用的命名模式作为参数。但是,它会通过在您提供的命名模式上附加一个递增的数字(1、2、3 等)来重命名。

                import os
                import sys
                
                # checking whether path and filename are given.
                if len(sys.argv) != 3:
                    print "Usage : python rename.py <path> <new_name.extension>"
                    sys.exit()
                
                # splitting name and extension.
                name = sys.argv[2].split('.')
                if len(name) < 2:
                    name.append('')
                else:
                    name[1] = ".%s" %name[1]
                
                # to name starting from 1 to number_of_files.
                count = 1
                
                # creating a new folder in which the renamed files will be stored.
                s = "%s/pic_folder" % sys.argv[1]
                try:
                    os.mkdir(s)
                except OSError:
                    # if pic_folder is already present, use it.
                    pass
                
                try:
                    for x in os.walk(sys.argv[1]):
                        for y in x[2]:
                            # creating the rename pattern.
                            s = "%spic_folder/%s%s%s" %(x[0], name[0], count, name[1])
                            # getting the original path of the file to be renamed.
                            z = os.path.join(x[0],y)
                            # renaming.
                            os.rename(z, s)
                            # incrementing the count.
                            count = count + 1
                except OSError:
                    pass
                

                希望这对你有用。

                【讨论】:

                  【解决方案11】:

                  我更喜欢为我必须做的每个替换编写一个小的衬里,而不是编写更通用和更复杂的代码。例如:

                  这会将当前目录中任何非隐藏文件中的所有下划线替换为连字符

                  import os
                  [os.rename(f, f.replace('_', '-')) for f in os.listdir('.') if not f.startswith('.')]
                  

                  【讨论】:

                  • 比其他方法容易得多。这就是我喜欢 Python 的原因。
                  • 今天浪费了太多时间试图弄清楚为什么我的“重命名”命令不起作用 - 应该先来这里!伟大的 Pythonic 单线!
                  • 不起作用,因为 Windows 在每个 rename 之后不断按字母顺序重新排序文件:(
                  • 非常好,但它只适用于没有子目录的目录。
                  • 如果你得到no such file error,请记住os.rename需要完整路径
                  【解决方案12】:

                  如果你不介意使用正则表达式,那么这个函数会给你重命名文件的强大功能:

                  import re, glob, os
                  
                  def renamer(files, pattern, replacement):
                      for pathname in glob.glob(files):
                          basename= os.path.basename(pathname)
                          new_filename= re.sub(pattern, replacement, basename)
                          if new_filename != basename:
                              os.rename(
                                pathname,
                                os.path.join(os.path.dirname(pathname), new_filename))
                  

                  所以在你的例子中,你可以这样做(假设它是文件所在的当前目录):

                  renamer("*.doc", r"^(.*)\.doc$", r"new(\1).doc")
                  

                  但您也可以回滚到初始文件名:

                  renamer("*.doc", r"^new\((.*)\)\.doc", r"\1.doc")
                  

                  还有更多。

                  【讨论】:

                    【解决方案13】:

                    这种重命名非常简单,例如使用 osglob 模块:

                    import glob, os
                    
                    def rename(dir, pattern, titlePattern):
                        for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):
                            title, ext = os.path.splitext(os.path.basename(pathAndFilename))
                            os.rename(pathAndFilename, 
                                      os.path.join(dir, titlePattern % title + ext))
                    

                    然后你可以像这样在你的例子中使用它:

                    rename(r'c:\temp\xx', r'*.doc', r'new(%s)')
                    

                    上面的示例会将c:\temp\xx 目录中的所有*.doc 文件转换为new(%s).doc,其中%s 是文件的前一个基本名称(不带扩展名)。

                    【讨论】:

                    • 命令os.path.join(dir, titlePattern % title + ext)中的%符号如何使用?我知道% 用于模运算,也用作格式化运算符。但通常后面跟着sf 来指定格式。为什么在上述命令中% 之后没有任何内容(空格)?
                    • @ShashankSawant 确实是一个格式化操作符。有关文档和示例用法,请参阅 String Formatting Operations
                    【解决方案14】:

                    试试:http://www.mattweber.org/2007/03/04/python-script-renamepy/

                    我喜欢拥有我的音乐、电影和 图片文件以某种方式命名。 当我从 互联网,他们通常不关注我的 命名约定。我寻找到了自我 手动重命名每个文件以适合我的 风格。这真的很快变老了,所以我 决定写一个程序来做 对我来说。

                    这个程序可以转换文件名 全部小写,替换字符串 任何你想要的文件名, 并修剪任意数量的字符 文件名的前面或后面。

                    该程序的源代码也可用。

                    【讨论】:

                    • 可惜链接失效了,有谁知道源码在哪里?
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2022-01-15
                    • 2021-04-04
                    • 1970-01-01
                    • 2015-01-23
                    • 2010-11-04
                    • 2018-06-27
                    • 1970-01-01
                    相关资源
                    最近更新 更多