2016-06-25 85 views
1

我想寫一些代碼來遞歸地重命名python中的文件。我有一個根文件夾,裏面有另一個文件夾,還有另一個文件夾。每個文件夾都有一個名爲「Name.txt」的文件,我想將它們更改爲「Test.txt」,以瞭解os.walk()和os.rename()如何工作。我寫這個代碼:python中的遞歸文件重命名

# -*- 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 

我在做什麼錯?

在此先感謝。

+0

您沒有正確使用'os.walk',請參閱(http://stackoverflow.com/questions/10989005/do-i-understand-os-walkright) – TemporalWolf

+0

您不應該發佈答案您的更新代碼。用您的更新編輯原始問題並刪除「答案」,因爲他們不回答問題。 – TemporalWolf

回答

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(".") 
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(".") 
0

摘要

建議的變化如下:

  • 使用os.getcwd(),而不是"."似乎因爲沒有得到解決你所希望的方式。這將在診斷功能中進行說明。
  • 使用相對路徑重命名os.chdir(root)。當然,使用正確絕對路徑也可以,但恕我直言相對路徑更加優雅。
  • 像其他人提到的那樣,將一個明確的字符串傳遞到os.walk()

另請注意,topdown=Falseos.walk()並不重要。由於您不重命名目錄,因此在os.walk()期間目錄結構將保持不變。

代碼示例

原始文件結構:

[email protected]:/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 

導致文件結構:

[email protected]:/mnt/ramdisk/test$ tree . 
. 
├── outer 
│   ├── inner 
│   │   └── renamed.txt 
│   └── renamed.txt 
├── renamed.txt 
└── rename.py 

下Debian測試8.6 64位,蟒2.7.1 2(Anaconda 4.1.1)。

對於診斷

# -*- 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()) 

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)不是所需 (不是說它'錯誤的)。它始終綁定到傳遞到os.walk()而不是包含文件f的路徑的參數path

  • "."作爲path通過時,os.path.join(root, f)中的點仍未完全解析。

示例代碼避免了這些含糊之處。