2010-06-24 87 views
5

我想學習使用python作爲命令行腳本替換。我過去花了一些時間用python,但這已經有一段時間了。這似乎在它的範圍之內。通過python跨文件夾中的所有文件進行搜索和替換?

我在一個文件夾中有幾個文件,我想在它們的內部進行搜索和替換。我想用python腳本來做。

例如,搜索並將「foo」的所有實例替換爲「foobar」。

回答

2

一般情況下我馬上拿出老perl -pi -e 's/foo/foobar/'這一點,但如果你想要的Python:

import os 
import re 
_replace_re = re.compile("foo") 
for dirpath, dirnames, filenames in os.walk("directory/"): 
    for file in filenames: 
     file = os.path.join(dirpath, file) 
     tempfile = file + ".temp" 
     with open(tempfile, "w") as target: 
      with open(file) as source: 
       for line in source: 
        line = _replace_re.sub("foobar", line) 
        target.write(line) 
     os.rename(tempfile, file) 

如果你使用的是Windows,你需要的os.rename(tempfile, file)前添加os.remove(file)

+0

另外,它可能是很好的把在一個小的檢查,以驗證'tempfile'不存在... – 2010-06-24 14:00:30

+0

這似乎是有道理的。創建臨時文件的行爲就是這樣,如果權限不夠,我們仍然可以執行該操作?在這種情況下,刪除和重命名也不起作用,對嗎? – fruit 2010-06-24 14:03:45

+0

tempfile確保我們不會太早覆蓋真實文件,以免我們在大文件上佔用大量內存(這樣做的理由很簡單:'data = open(file ).read(); data = _replace_re.sub(「foobar」,data); open(file,「w」)。write(data)',但會使用大量內存,並且如果計算機崩潰一半'write',你會丟失未寫入的數據) – 2010-06-24 14:53:17

1

我通過它工作,這似乎工作,但任何可以指出的錯誤將是真棒。

import fileinput, sys, os 

def replaceAll(file, findexp, replaceexp): 
    for line in fileinput.input(file, inplace=1): 
     if findexp in line: 
      line = line.replace(findexp, replaceexp) 
     sys.stdout.write(line) 

if __name__ == '__main__': 
    files = os.listdir("c:/testing/") 
    for file in files: 
     newfile = os.path.join("C:/testing/", file) 
     replaceAll(newfile, "black", "white") 

對此的擴展將移動到文件夾內的文件夾。

+0

你可能想要做的是把它改爲'replaceAll(file,「black」,「white」)' - 如果你有'somedir/blackdir/blackfile.txt「,那麼你會得到'somedir/whitedir/whitefile.txt'。當然,除非你想要那樣,在這種情況下,請保持它的樣子。 – 2010-06-24 15:20:58

+0

這個函數爲什麼要重命名文件?它正在逐行搜索它.. – fruit 2010-06-24 16:42:21

5

歡迎來到StackOverflow。既然你想學習你自己(+1),我只是給你一些指點。

查看os.walk()獲取所有文件。

然後迭代文件中的每一行(for line in currentfile:在這裏派上用場)。

現在,你需要知道,如果你想要一個「笨」替換(查找/替換每個foo即使是在一個字的中間(比如foobar - 你想foofoobar結果)或智能更換?

對於前者,看str.replace(),對於後者,看re.sub(),弄清r'\bfoo\b'手段。

+0

很酷,謝謝!學習新功能(os.walk())總是很好。它是否也遍歷子目錄?我假設你的鏈接會告訴我。 – fruit 2010-06-24 14:01:38

+0

是的,它的確如此:) – 2010-06-24 14:02:57

0

這是一種選擇,因爲你必須呈現給你不同的Python的解決方案,最有用的工具(根據我的說法),在Unix/Windows中,GNU find命令和替換工具(如sed/awk)來搜索f iles(遞歸)並進行替換,像這樣的簡單命令可以做到這一點(語法來自內存,未經測試)。這表示,找到所有文本文件和改變,同時這個詞在內容上「老」到「新」,用sed備份原始文件...

$ find /path -type f -iname "*.txt" -exec sed -i.bak 's/old/new/g' "{}" +; 
相關問題