2012-11-28 28 views
0

我試圖讀取兩個文件,並將其中一個文件的內容替換爲文件夾中的其他文件的內容,該文件夾中也存在子目錄。 但它告訴子過程沒有定義。 我是新來的蟒蛇和shell腳本可以有人幫助我這個請嗎?如何替換文件夾中多個文件中的字符串?

import os 
import sys 
import os.path 

f = open ("file1.txt",'r') 
g = open ("file2.txt",'r') 
text1=f.readlines() 
text2=g.readlines() 

i = 0; 
for line in text1: 
    l = line.replace("\r\n", "") 
    t = text2[i].replace("\r\n", "") 
    args = "find . -name *.tml" 
    Path = subprocess.Popen(args , shell=True) 
    os.system(" sed -r -i 's/" + l + "/" + t + "/g' " + Path) 
    i = i + 1; 
+0

到目前爲止,該腳本所做的是假定兩個文件具有相同的行數(或者第二個至少比第一個長)。對於每一行,它都會產生一個子進程,每次執行相同的find命令,但對結果沒有任何影響。然後使用os.system產生另一個子進程,它執行一個sed命令,我不清楚結果。 – jdi

+0

@jdi用sed命令m試圖用路徑中存在的所有文件中file2的內容(line be line)替換file1中的內容。 – harry

+0

@jdi新來的蟒蛇不知道哪裏去錯了..如果你能幫我出 – harry

回答

0

要重點解決您的實際的錯誤,你需要導入的子模塊,你在你的代碼,利用它(奇怪):

import subprocess 

之後,你會發現更多的問題。我會盡量使我的建議儘可能簡單。先編碼,然後我會分解它。請記住,有更強大的方法來完成這項任務。但我正在盡力記住您的經驗水平,並儘可能使您的當前方法儘可能接近。

import subprocess 
import sys 

# 1 
results = subprocess.Popen("find . -name '*.tml'", 
          shell=True, stdout=subprocess.PIPE) 

if results.wait() != 0: 
    print "error trying to find tml files" 
    sys.exit(1) 

# 2 
tml_files = [] 
for tml in results.stdout: 
    tml_files.append(tml.strip()) 

if not tml_files: 
    print "no tml files found" 
    sys.exit(0) 

tml_string = " ".join(tml_files) 

# 3 
with open ("file1.txt") as f, open("file2.txt") as g: 
    while True: 
# 4 
     f_line = f.readline() 
     if not f_line: 
      break 

     g_line = g.readline() 
     if not g_line: 
      break 

     f_line = f_line.strip() 
     g_line = g_line.strip() 
     if not f_line or not g_line: 
      continue 
# 5 
     cmd = "sed -i -e 's/%s/%s/g' %s" % \ 
       (f_line.strip(), g_line.strip(), tml_string) 

     ret = subprocess.Popen(cmd, shell=True).wait() 
     if ret != 0: 
      print "error doing string replacement" 
      sys.exit(1) 

您不需要一次讀入整個文件。如果它們很大,這可能是很多內存。您可以一次使用一行代碼,並且還可以在打開文件時使用所謂的「上下文管理器」。這將確保他們正常關閉無論發生什麼事情:

  1. 我們開始與只運行一次找到所有你.tml文件子命令。您的版本具有多次運行相同的命令。如果搜索路徑相同,那麼我們只需要它一次。這將檢查命令的退出代碼並退出,如果失敗。

  2. 我們在子流程命令上循環使用stdout,並將已刪除的行添加到列表中。這是您的replace("\r\n")更健壯的方式。它刪除空白。 「列表理解」在這裏更適合(下線)。如果我們沒有找到任何tml文件,那麼我們沒有工作要做,所以我們退出。否則,我們將它們連接在一個空格分隔的字符串中,以便稍後適合我們的命令。

  3. 這被稱爲「上下文管理器」。您可以用一種方式打開文件,不管它們將被正確關閉。該文件對該代碼塊中的上下文的長度打開。我們將永遠循環,並在適當的時候中斷。

  4. 我們從每個文件中一次一行地拖出一行。如果任何一行都是空白的,我們就會到達文件末尾,無法再做任何工作,所以我們就爆發了。然後我們去掉換行符,如果任何一個字符串是空的(空白行),我們仍然不能做任何工作,但是我們繼續到下一個可用的行。

  5. 您的sed命令的修改版本。我們在源代碼和替換字符串的每個循環上構造命令字符串,並添加tml文件字符串。請記住,這是一個非常天真的替代方法。它真的希望你的替換字符串是安全的字符,不要打破sed格式。但我們用另一個subprocess命令運行。 wait()只是等待返回碼,我們檢查它是否有錯誤。此方法取代您的os.system()版本。

希望這會有所幫助。最終你可以改善這一點,做更多的檢查和安全操作。

+0

是的,我試過了,我在代碼中也改變了args =「[find。-name * .tml]」。但是現在錯誤似乎是「無法讀取路徑」 – harry

+0

我想要做的是讀取兩個文件並存儲它。 然後刪除所有新行字符。 然後,我想搜索file1的內容,特別是directoy(它有文件和子目錄),並將其替換爲file2的相應內容。 你可以爲我推薦任何其他解決方案嗎? – harry

+0

它顯示語法錯誤在「打開」 你可以請檢查一次嗎? – harry

相關問題