【问题标题】:Python: Retrieving and renaming indexed files in a directoryPython:检索和重命名目录中的索引文件
【发布时间】:2017-07-30 21:24:42
【问题描述】:

我创建了一个脚本来重命名给定目录中的索引文件

例如,如果目录有以下文件 >> (bar001.txt, bar004.txt, bar007.txt, foo2.txt, foo5.txt, morty.dat, rick.py)。我的脚本应该能够“仅”重命名索引文件并像这样关闭间隙>>(bar001.txt、bar002.txt、bar003.txt、foo1.txt、foo2.txt...)。

我把完整的脚本放在下面,但它不起作用。该错误是合乎逻辑的,因为没有给出错误消息,但目录中的文件保持不变。

#! python3

import os, re

working_dir = os.path.abspath('.')

# A regex pattern that matches files with prefix,numbering and then extension
pattern = re.compile(r'''
    ^(.*?)        # text before the file number
    (\d+)         # file index
    (\.([a-z]+))$ # file extension
''',re.VERBOSE)

# Method that renames the items of an array
def rename(array):
    for i in range(len(array)):
        matchObj = pattern.search(array[i])
        temp = list(matchObj.group(2))
        temp[-1] = str(i+1)
        index = ''.join(temp)
        array[i] = matchObj.group(1) + index + matchObj.group(3)
    return(array)

array = []
directory = sorted(os.listdir('.'))

for item in directory:
    matchObj = pattern.search(item)
    if not matchObj:
        continue
    if len(array) == 0 or matchObj.group(1) in array[0]:
        array.append(item)
    else:
        temp = array
        newNames = rename(temp)
        for i in range(len(temp)):
            os.rename(os.path.join(working_dir,temp[i]),
                        os.path.join(working_dir,newNames[i]))
        array.clear() #reset array for other files
        array.append(item) 

【问题讨论】:

  • 我假设你也想要bar005.txtbar006.txt?
  • 将它们重命名为什么?
  • 其实,没有。您打算通过重命名以后的文件来缩小差距。你的想法有点任务重。一旦我或者如果我克服了这个问题,我可能会考虑自己解决它。
  • 例如 spam01, spam03 , spam04 应该重命名为 spam01, spam02, spam 03。这就是我通过重命名来填补空白的意思。所以基本上,使用第一个文件的格式和第一个文件的索引重命名后面的文件。
  • 好的,那么如果有三个以spam开头的文件,它们应该以01、02、03结尾。

标签: python python-3.x filesystems file-management


【解决方案1】:

总而言之,您希望找到名称以数字结尾的每个文件,并且 为每组具有相同名称的文件填写空白,保留数字后缀。您不想创建任何新文件;相反,应该使用具有最高数字的那些来填补空白。

由于此摘要可以很好地转换为代码,因此我将这样做而不是处理您的代码。

import re
import os

from os import path

folder  = 'path/to/folder/'
pattern = re.compile(r'(.*?)(\d+)(\.[a-z]+)$')
summary = {}

for fn in os.listdir(folder):
  m = pattern.match(fn)
  if m and path.isfile(path.join(folder, fn)):
    # Create a key if there isn't one, add the 'index' to the set
    # The first item in the tuple - len(n) - tells use how the numbers should be formatted later on
    name, n, ext = m.groups()
    summary.setdefault((name, ext), (len(n), set()))[1].add(int(n))

for (name, ext), (n, current) in summary.items():
  required = set(range(1, len(current)+1)) # You want these
  gaps     = required - current            # You're missing these
  superfluous = current - required         # You don't need these, so they should be renamed to fill the gaps

  assert(len(gaps) == len(superfluous)), 'Something has gone wrong'

  for old, new in zip(superfluous, gaps):
      oldname = '{name}{n:>0{pad}}{ext}'.format(pad=n, name=name, n=old, ext=ext)
      newname = '{name}{n:>0{pad}}{ext}'.format(pad=n, name=name, n=new, ext=ext)

      print('{old} should be replaced with {new}'.format(old=oldname, new=newname))

我认为这差不多涵盖了它。

【讨论】:

  • 它不起作用。它打印出文件应该已被替换,但它们没有。
  • 看代码。我只是告诉你你需要做什么。将print 替换为重命名逻辑,您就可以排序了。
  • 这更有意义
  • 好。在这种情况下,你想接受答案,结束吗?
  • zip 将两个或多个集合中的项目配对(例如,zip('123', 'abc') 将给您('1', 'a'),然后是('2', 'b'),最后是('3', 'c')
猜你喜欢
  • 1970-01-01
  • 2021-01-25
  • 2013-08-15
  • 2013-09-20
  • 1970-01-01
  • 2018-10-02
  • 2011-05-01
  • 2012-08-01
  • 2023-03-27
相关资源
最近更新 更多