【问题标题】:Rename multiple files in a directory in Python [duplicate]在Python中重命名目录中的多个文件[重复]
【发布时间】:2011-02-15 02:07:30
【问题描述】:

我正在尝试使用 Python 重命名目录中的一些文件。

假设我有一个名为 CHEESE_CHEESE_TYPE.*** 的文件并想删除 CHEESE_,所以我的结果文件名将是 CHEESE_TYPE

我正在尝试使用os.path.split,但它无法正常工作。我也考虑过使用字符串操作,但也没有成功。

【问题讨论】:

  • 您的针不在大海捞针中,您的大海捞针有一个通配符,即使忽略大小写,您的结果也不能来自大海捞针。想澄清一下这个问题吗?
  • 好的,我会尽力清理它。我有一个文件文件夹,所有文件都命名为 cheese_cheese_type.prj (前 15 个字符相同,但尾随 4 个字符和扩展名不同)我试图从文件名中删除前 8 个字符(在示例中,'cheese_ ' 将被删除,生成的文件名将是 cheese_type.prj 所以我要做的是遍历目录,拆分文件名,并从文件名中删除前 8 个字符。输入将是 cheese_cheese_type.prj,输出将是 cheese_type。谢谢!

标签: python file-io file-rename


【解决方案1】:

此命令将从当前目录中的所有文件中删除 initial "CHEESE_" 字符串,使用 renamer:

$ renamer --find "/^CHEESE_/" *

【讨论】:

  • npm (JavaScript) ≠ python。还不如链接到 Perl rename 命令。
【解决方案2】:

这对我有用。

import os
for afile in os.listdir('.'):
    filename, file_extension = os.path.splitext(afile)
    if not file_extension == '.xyz':
        os.rename(afile, filename + '.abc')

【讨论】:

    【解决方案3】:

    使用os.rename(src, dst) 重命名或移动文件或目录。

    $ ls
    cheese_cheese_type.bar  cheese_cheese_type.foo
    $ python
    >>> import os
    >>> for filename in os.listdir("."):
    ...  if filename.startswith("cheese_"):
    ...    os.rename(filename, filename[7:])
    ... 
    >>> 
    $ ls
    cheese_type.bar  cheese_type.foo
    

    【讨论】:

    • 我从 windows 收到一个错误,说它找不到文件,它什么也没做......有什么提示吗?
    • @Jeff 我发现保存脚本并将其放置在我将运行它的目录中要容易得多。这样,os.rename 方法可以正常工作。缺点是您最终可能会重命名脚本本身。除了使用. 作为目录,您可以创建一个名为dir 的变量并使用它,然后将dir 添加到filename
    • 您得到“找不到文件”,因为文件名不是绝对路径。在调用重命名之前显式调用 path 和 os.path.join(path, filename) 它将起作用.
    • 最好有完整路径和传递给 os.rename 的文件名,而不仅仅是一个文件名。
    【解决方案4】:

    导入操作系统 导入字符串 def rename_files():

    #List all files in the directory
    file_list = os.listdir("/Users/tedfuller/Desktop/prank/")
    print(file_list)
    
    #Change current working directory and print out it's location
    working_location = os.chdir("/Users/tedfuller/Desktop/prank/")
    working_location = os.getcwd()
    print(working_location)
    
    #Rename all the files in that directory
    for file_name in file_list:
        os.rename(file_name, file_name.translate(str.maketrans("","",string.digits)))
    

    重命名文件()

    【讨论】:

      【解决方案5】:

      我最初是在寻找一些允许使用正则表达式重命名并在应用更改之前预览结果的 GUI。

      在 Linux 上,我成功使用了krename,在 Windows 上,Total Commander 确实使用正则表达式重命名,但我没有找到适合 OSX 的免费等价物,所以我最终编写了一个递归工作的 Python 脚本,默认情况下只打印新的文件名而不做任何更改。添加“-w”开关以实际修改文件名。

      #!/usr/bin/python
      # -*- coding: utf-8 -*-
      
      import os
      import fnmatch
      import sys
      import shutil
      import re
      
      
      def usage():
          print """
      Usage:
              %s <work_dir> <search_regex> <replace_regex> [-w|--write]
      
              By default no changes are made, add '-w' or '--write' as last arg to actually rename files
              after you have previewed the result.
              """ % (os.path.basename(sys.argv[0]))
      
      
      def rename_files(directory, search_pattern, replace_pattern, write_changes=False):
      
          pattern_old = re.compile(search_pattern)
      
          for path, dirs, files in os.walk(os.path.abspath(directory)):
      
              for filename in fnmatch.filter(files, "*.*"):
      
                  if pattern_old.findall(filename):
                      new_name = pattern_old.sub(replace_pattern, filename)
      
                      filepath_old = os.path.join(path, filename)
                      filepath_new = os.path.join(path, new_name)
      
                      if not filepath_new:
                          print 'Replacement regex {} returns empty value! Skipping'.format(replace_pattern)
                          continue
      
                      print new_name
      
                      if write_changes:
                          shutil.move(filepath_old, filepath_new)
                  else:
                      print 'Name [{}] does not match search regex [{}]'.format(filename, search_pattern)
      
      if __name__ == '__main__':
          if len(sys.argv) < 4:
              usage()
              sys.exit(-1)
      
          work_dir = sys.argv[1]
          search_regex = sys.argv[2]
          replace_regex = sys.argv[3]
          write_changes = (len(sys.argv) > 4) and sys.argv[4].lower() in ['--write', '-w']
          rename_files(work_dir, search_regex, replace_regex, write_changes)
      

      示例用例

      我想按以下方式翻转文件名的一部分,即将位 m7-08 移动到文件名的开头:

      # Before:
      Summary-building-mobile-apps-ionic-framework-angularjs-m7-08.mp4
      
      # After:
      m7-08_Summary-building-mobile-apps-ionic-framework-angularjs.mp4
      

      这将执行试运行,并打印新文件名而不实际重命名任何文件:

      rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1"
      

      这将进行实际的重命名(您可以使用-w--write):

      rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1" --write
      

      【讨论】:

      【解决方案6】:

      为了简单起见,您可以使用 os.system 函数并调用 bash 来完成任务:

      import os
      os.system('mv old_filename new_filename')
      

      【讨论】:

      • 这仅适用于 posix 系统。
      【解决方案7】:

      以下代码应该可以工作。它获取当前目录中的每个文件名,如果文件名包含模式CHEESE_CHEESE_,则将其重命名。如果不是,则对文件名不做任何事情。

      import os
      for fileName in os.listdir("."):
          os.rename(fileName, fileName.replace("CHEESE_CHEESE_", "CHEESE_"))
      

      【讨论】:

        【解决方案8】:

        我有同样的问题,我想将任何 pdf 文件中的空格 替换为破折号 -。 但是这些文件位于多个子目录中。所以,我不得不使用os.walk()。 在您的多个子目录的情况下,它可能是这样的:

        import os
        for dpath, dnames, fnames in os.walk('/path/to/directory'):
            for f in fnames:
                os.chdir(dpath)
                if f.startswith('cheese_'):
                    os.rename(f, f.replace('cheese_', ''))
        

        【讨论】:

          【解决方案9】:

          这是一个更通用的解决方案:

          此代码可用于从目录中的所有文件名中递归删除任何特定字符或字符集,并将它们替换为任何其他字符、字符集或无字符。

          import os
          
          paths = (os.path.join(root, filename)
                  for root, _, filenames in os.walk('C:\FolderName')
                  for filename in filenames)
          
          for path in paths:
              # the '#' in the example below will be replaced by the '-' in the filenames in the directory
              newname = path.replace('#', '-')
              if newname != path:
                  os.rename(path, newname)
          

          【讨论】:

            【解决方案10】:

            这类东西非常适合具有 shell 集成的 IPython。

            In [1] files = !ls
            In [2] for f in files:
                       newname = process_filename(f)
                       mv $f $newname
            

            注意:要将其存储在脚本中,请使用 .ipy 扩展名,并在所有 shell 命令前加上 !

            另请参阅:http://ipython.org/ipython-doc/stable/interactive/shell.html

            【讨论】:

            • 每一行的作用是什么?
            【解决方案11】:

            试试这个:

            import os
            import shutil
            
            for file in os.listdir(dirpath):
                newfile = os.path.join(dirpath, file.split("_",1)[1])
                shutil.move(os.path.join(dirpath,file),newfile)
            

            我假设您不想删除文件扩展名,但您可以使用句点进行相同的拆分。

            【讨论】:

            • 覆盖内置的“文件”通常是不好的做法。
            • @bukzor 7 年后,我将对此进行扩展:“覆盖内置函数通常是不好的做法。”
            【解决方案12】:

            假设您已经在目录中,并且您评论中的“前 8 个字符”始终成立。 (虽然“CHEESE_”是7个字符...?如果是的话,把下面的8改成7)

            from glob import glob
            from os import rename
            for fname in glob('*.prj'):
                rename(fname, fname[8:])
            

            【讨论】:

              【解决方案13】:

              这是基于您最新评论的脚本。

              #!/usr/bin/env python
              from os import rename, listdir
              
              badprefix = "cheese_"
              fnames = listdir('.')
              
              for fname in fnames:
                  if fname.startswith(badprefix*2):
                      rename(fname, fname.replace(badprefix, '', 1))
              

              【讨论】:

                【解决方案14】:

                这个呢:

                import re
                p = re.compile(r'_')
                p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***
                

                【讨论】:

                • 这不能回答问题!
                【解决方案15】:

                您的问题似乎更多在于确定新文件名而不是重命名本身(您可以使用 os.rename 方法)。

                从您的问题中不清楚您想要重命名的模式是什么。字符串操作没有错。这里可能需要正则表达式。

                【讨论】:

                  猜你喜欢
                  • 2016-09-24
                  • 1970-01-01
                  • 2018-05-08
                  • 2018-11-01
                  • 1970-01-01
                  • 2012-12-27
                  • 2018-08-29
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多