2016-06-25 22 views
1

私はpythonでファイルの名前を再帰的に変更するコードを書くことを試みています。私はそれの中に別のフォルダを持っているルートフォルダと、そのフォルダの中のさらに別のフォルダを持っています。それぞれのフォルダには "Name.txt"という名前のファイルがあり、os.walk()とos.rename()がどのように動作するかを理解するために、それらのファイルを "Test.txt"に変更したいと思います。私はこのコードを書いている: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-walk-right) – TemporalWolf

+0

あなたはあなたの更新されたコード。あなたのアップデートでオリジナルの質問を編集し、質問に答えないので「回答」を削除してください。 – TemporalWolf

答えて

0

os.renameは破壊的である可能性があります。注意して使用してください。

あなたはsomethasonのためにos.walkに初期化されたrootstructureを持っていました。現在のディレクトリのパスに初期化する必要があります。

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)で使用してください。もちろんを使用すると、絶対パスのも有効ですが、IMHOの相対パスはより洗練されています。
  • 他にも言及しているように、明確な文字列をos.walk()に渡します。

topdown=False,os.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 

たファイル構造:Debianでテスト済み

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

8.6 64ビット、パイソン2.7.1 2(アナコンダ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)が希望ない (それを言わないで '間違っている)。常にファイルfを含むパスの代わりにos.walk()に渡されたパラメータpathにバインドされます。

  • pathとして"."が渡された場合、os.path.join(root, f)のドットはまだ完全には解決されていません。

サンプルコードは、これらのあいまいさを避けています。

関連する問題