【问题标题】:Rename files in a directory with incremental index使用增量索引重命名目录中的文件
【发布时间】:2017-08-08 00:14:35
【问题描述】:

输入:我想将递增的数字添加到按日期排序的目录中的文件名。例如,将“01_”、“02_”、“03_”...添加到下面的这些文件中。

test1.txt (oldest text file)
test2.txt
test3.txt
test4.txt (newest text file)

这是目前为止的代码。我可以获取文件名,但文件名中的每个字符似乎都是列表中自己的项目。

import os
for file in os.listdir("/Users/Admin/Documents/Test"):
if file.endswith(".txt"):
      print(file)

预期结果是:

   01_test1.txt
   02_test2.txt
   03_test3.txt
   04_test4.txt

test1 是最旧的,test 4 是最新的。

如何为每个文件名添加 01_、02_、03_、04_?

我尝试过这样的事情。但它会在文件名中的每个字符中添加一个“01_”。

new_test_names = ['01_'.format(i) for i in file]
print (new_test_names)

【问题讨论】:

  • 您是否希望拥有一个与您文件名中现有数字无关的独立计数器?或者您是否希望在文件名中使用数字并将其也设置在文件的开头?
  • 如果您希望它们按年龄顺序重命名,您需要 os.listdir 后跟 sorted on os.path.getmtime。嗯...如果这确实是您的要求,我可能需要重新打开它,但是您没有在问题中明确说明,所以这点就在您身上。
  • @StacyM 将其明确添加到您的问题中,并使其更清晰一些。我会重新打开它。
  • 还要清楚它是否只是 .txt 文件或特定目录中的所有内容。细节很重要。
  • @StacyM 没有人会因为你不知道网站的运作方式而禁止你。 :) 无论如何,我不相信任何答案都能解决您对基于年龄编号的担忧,所以我冒昧地添加了我自己的答案。记住你可以accept the answer that helped you the most(仔细想想,因为你只能接受1。

标签: python filenames prepend


【解决方案1】:
  1. 如果要按年龄对文件进行编号,则需要先对它们进行排序。您调用sorted 并传递key 参数。函数os.path.getmtime 将按年龄升序排序(从最旧到最新)。

  2. 使用glob.glob 获取给定目录中的所有 文本文件。目前它不是递归的,但如果你使用 python3,递归扩展是一个最小的附加。

  3. str.zfill 用于0x_ 形式的字符串

  4. 使用os.rename 重命名您的文件

import glob
import os

sorted_files = sorted(
    glob.glob('path/to/your/directory/*.txt'), key=os.path.getmtime)

for i, f in enumerate(sorted_files, 1):
    try:
        head, tail = os.path.split(f)            
        os.rename(f, os.path.join(head, str(i).zfill(2) + '_' + tail))
    except OSError:
        print('Invalid operation')

使用try-except 进行检查总是有帮助的,以发现任何不应该发生的错误。

【讨论】:

  • 您的格式有点错误。我还是推荐'{:02d}_{}'.format(i, f),但你的可以用str(i).zfill(2) + '_' + f之类的东西来修复。
  • @smarx 哦,这更简单。谢谢!
  • @StacyM 它不会中断。它不再附加0。这就是 zfill 的工作原理。如果你的文件超过 99 个,我推荐.zfill(3) 而不是 2。
  • @StacyM 将其转换为列表:list((os.path.basename(x) for x in sorted_files))
  • @StacyM Ohhhh 现在我明白了这个问题。 不要那样使用os.path.basenameos.rename 需要完整路径。我已经对我的答案进行了编辑。希望能做到。
【解决方案2】:

这应该可行:

import glob

new_test_names = ["{:02d}_{}".format(i, filename) for i, filename in enumerate(glob.glob("/Users/Admin/Documents/Test/*.txt"), start=1)]

或者没有列表理解:

for i, filename in enumerate(glob.glob("/Users/Admin/Documents/Test/*.txt"), start=1):
    print("{:02d}_{}".format(i, filename))

在这里要了解三件事:

  1. glob,这使得这种文件匹配更容易。
  2. enumerate,它可以让你编写一个带有索引变量的循环。
  3. format,特别是 02d 修饰符,它打印两位数(零填充)。

【讨论】:

  • 我会说同样的话,减去glob(我认为这是一个很好的补充),然后我会使用enumerate(glob.glob(path), 1)来避免i + 1
  • 不错的改进!刚刚编辑以包含它。谢谢。
【解决方案3】:
test_dir = '/Users/Admin/Documents/Test'
txt_files = [file
             for file in os.listdir(test_dir)
             if file.endswith('.txt')]
numbered_files = ['%02d_%s' % (i + 1, file)
                  for i, file in enumerate(txt_files)]

【讨论】:

    【解决方案4】:

    用前导零格式化整数的两种方法。

    1.使用.format

    import os
    i = 1
    for file in os.listdir("/Users/Admin/Documents/Test"):
        if file.endswith(".txt"):
            print('{0:02d}'.format(i) + '_' + file)
            i+=1
    

    2.使用.zfill

    import os
    i = 1
    for file in os.listdir("/Users/Admin/Documents/Test"):
        if file.endswith(".txt"):
            print(str(i).zfill(2) + '_' + file)
            i+=1
    

    【讨论】:

      【解决方案5】:

      最简单的方法是简单地使用一个变量,例如i,它将保存数字并使用某种formatting 将其添加到字符串前面,以保证它至少有2 位数字:

      import os
      
      i = 1
      for file in os.listdir("/Users/Admin/Documents/Test"):
        if file.endswith(".txt"):
              print('%02d_%s' % (i, file)) # %02d means your number will have at least 2 digits
              i += 1
      

      您还可以查看 enumerateglob 以使您的代码更短(但请确保您在使用之前了解基础知识)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 2021-04-04
        • 2012-01-17
        • 2021-05-10
        • 2021-06-09
        • 2015-10-08
        相关资源
        最近更新 更多