python中的递归文件重命名

时间:2016-06-25 18:07:34

标签: python recursion

我试图编写一些代码来递归地重命名python中的文件。我有一个根文件夹,里面有另一个文件夹,还有该文件夹中的另一个文件夹。每个文件夹都有一个名为" Name.txt"我想将它们更改为" Test.txt",以便了解os.walk()和os.rename()的工作原理。我写了这段代码:

# -*- coding: utf-8 -*-

import os


def renamefiles(path):

    rootstructure=os.walk(path,topdown=False)
    for root,dirs,files in os.walk(rootstructure):

        for filenames in files:

        fullfilename=os.path.abspath(filenames)

        os.rename(fullfilename,"Test.txt")



renamefiles(".")

然而,我收到此错误:

File "/usr/lib/python2.7/os.py", line 278, in walk
names = listdir(top)
TypeError: coercing to Unicode: need string or buffer, generator found

我做错了什么?

提前致谢。

3 个答案:

答案 0 :(得分:0)

os.rename可能具有破坏性。仔细使用它。

您已将rootstructure初始化为os.walk以获得某种原因。您需要将其初始化为当前目录的路径。

import os

def renamefiles(path):
    rootstructure=os.path.abspath(path)

    for root,dirs,files in os.walk(rootstructure):
        for filenames in files:
            fullfilename=os.path.abspath(filenames)
            print(fullfilename)
            # Use this carefuly, it can wipe off your entire system
            # if not used carefully
            os.rename(fullfilename,"Test.txt")

renamefiles(".")

答案 1 :(得分:0)

您需要将表示路径的字符串传递给os.walk。目前,您正在传递rootstructure,这是一个生成器对象。

def renamefiles(path):
    for root,dirs,files in os.walk(path):
        for filenames in files:
            fullfilename=os.path.abspath(filenames)

            # YOU PROBABLY WANT TO CHECK THE FILENAME BEFORE RENAMING!
            # WHAT IF THE FILE IS NOT Name.txt !
            os.rename(fullfilename,"Test.txt")

renamefiles(".")

答案 2 :(得分:0)

摘要

建议的更改如下:

  • 使用"."代替os.chdir(root),因为它似乎无法以您想要的方式解决。这将在诊断功能中说明。
  • os.walk()使用相对路径重命名。当然使用正确的绝对路径也可以,但恕我直言的相对路径更优雅。
  • 将其他人提到的明确字符串传递给topdown=False

另请注意,os.walk()中的os.walk()并不重要。由于您没有重命名目录,因此目录结构在bill@Bill-deb:/mnt/ramdisk/test$ tree . . ├── outer │   ├── inner │   │   └── innermost.txt │   └── inner.txt ├── outer.txt └── rename.py 期间将保持不变。

代码示例

原始文件结构:

# -*- coding: utf-8 -*-

import os

def renamefiles(path):

    for root, dirs, files in os.walk(path, topdown=False):
        for f in files:
            # chdir before renaming
            os.chdir(root)  
            if f != "rename.py":  # avoid renaming this file
                os.rename(f, "renamed.txt")  # relative path, more elegant


renamefiles(os.getcwd())  # pass an unambiguous string

代码:

bill@Bill-deb:/mnt/ramdisk/test$ tree .
.
├── outer
│   ├── inner
│   │   └── renamed.txt
│   └── renamed.txt
├── renamed.txt
└── rename.py

结果文件结构:

# -*- coding: utf-8 -*-

import os

def renamefiles_check(path):

    for root, dirs, files in os.walk(path, topdown=False):

        for f in files:
            print "========="
            print "os.getcwd() = {}".format(os.getcwd())
            print "root = {}".format(root)
            print "f = {}".format(f)
            print "os.path.abspath(f) = {}".format(os.path.abspath(f))
            print "os.path.join(root, f) = {}".format(os.path.join(root, f))

# renamefiles_check(".")
# renamefiles_check(os.getcwd())

在debian 8.6 64位,python 2.7.12(Anaconda 4.1.1)下测试。

用于诊断

renamefiles_check(".")

此处显示os.getcwd() = /mnt/ramdisk/test root = ./outer/inner f = innermost.txt os.path.abspath(f) = /mnt/ramdisk/test/innermost.txt os.path.join(root, f) = ./outer/inner/innermost.txt 的前几行:

os.path.abspath(f)

您可以验证:

  • 行为path不是期望的(更不用说它错了)。它始终绑定到传递到os.walk()的参数f,而不是包含文件"."的路径。

  • path作为os.path.join(root, f)传递时,evaluate_essay中的点仍未完全解析。

示例代码避免了这些歧义。