2011-05-02 83 views
2

我想在下面的文件中以特定間隔(例如每30分鐘)更改omega的值。該文件在運行時由另一個程序使用。我想慢慢地從0-10斜坡RPM值(線上的最後一個入口)。基本上,下面的文件中的值「5」需要以每30分鐘1次的增量從0-10變化。在python中每20分鐘編輯一個文件中的特定單詞

rotor 
{ 
    // Fixed patches (by default they 'move' with the MRF zone) 
    nonRotatingPatches(); //if something blows up ..fill the non rotating patches between "(baffles, pressureOutlet etc)" 

    origin origin [0 1 0 0 0 0 0] (0 0 0); 
    axis  axis [0 0 0 0 0 0 0] (0 0 1); 
    omega omega [0 0 -1 0 0 0 0] 5; 
} 

我曾嘗試下面的代碼(我不知道該怎麼辦的,每30分鐘部分),而是由file.writelines(data)方法寫入的數據似乎並沒有納入我作出值的變化。

import os 
import sys 
import fileinput 

with open('MRFzones', 'r') as file: 
    data = file.readlines() 

# The line omega is line 27 in the file. 
line = data[26] 
word = line.split() 

# >>> data[26].split() 
# ['omega', 'omega', '[0', '0', '-1', '0', '0', '0', '0]', '5;'] 
# The part i want to change is the 10th word. 
word[9] = '10;' 

# Write everything back. 
with open('MRFzones', 'w') as file: 
    file.writelines(data) 

這是行不通的 - 在更新的文件中5未被更改爲10。有人可以幫我實施嗎?我可能甚至沒有正確的想法,所以我們可以在必要時從頭開始編寫代碼。

感謝, 蘇雷什

回答

2

你是不是修改data在所有 - 你提取lineword和修改的。最後,您將原始文件data寫回文件。

我不會使用Python這一點,而是一個shell腳本(前提是你在一個類Unix操作系統):

for i in 0 1 2 3 4 5 6 7 8 9 10; do 
    sleep 30 
    sed -i "26s/[0-9]+;/$i/" MRFzones 
od 
+0

THA nks的響應..我正在學習Python,並試圖使用該程序做一些自動化!是的,我在unix中使用了類似的腳本來做同樣的事情。你的要簡單得多,但是一般情況下應該使用python!? -suresh – Suresh 2011-05-02 08:30:59

+0

@user:我明白了,如果你的目標是學習Python而不是完成任務:)我的答案並不是非常有用:) – 2011-05-02 08:33:41

+0

就像我說的那樣..工作正在完成,但我也想知道如果我不得不使用Python,我將如何去呢? – Suresh 2011-05-02 08:39:03

1

您可以通過fileinput模塊識別您的線路及其組件您導入和正則表達式的re模塊:

>>> import re 
>>> pattern = r'(\s*omega\s+omega\s+\[-?\d+ -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ -?\d+\]) (-?\d+);' 

花括號是用來捕捉模式,看看在re module瞭解更多(非常有用的Python模塊,非常出色地完成和記錄)!

我們有我們的模式,現在在我們的文件就地瀏覽:print用於直接在文件中寫入(不再打印到屏幕),當for循環結束(文件關閉)時標準功能恢復正常。

不要忘記刪除換行符以避免在輸出文件中出現不需要的換行符(是的,這有點煩人:循環給出的line變量包含換行符\n)!

>>> from fileinput import FileInput 
>>> path = 'D:\\Temp\\Toto.txt' 
>>> for line in FileInput(path, inplace=1): 
     line = line.replace('\n', '') 
     match = re.match(pattern, line) 
     if match: 
      line = '{0} {1};'.format(match.groups()[0], '145') 
      print line 
     else: 
      print line 

現在,您可以瀏覽您的舊文件,該值5145取代。 我個人不同意斯文,Python對我來說是處理這種情況的完美語言。

+0

+1對'inplace = 1'。代碼可以改進,但(見我的答案)。 – EOL 2011-05-02 10:00:22

1

做你想做的事情的規範方式確實是使用正則表達式模塊(re)。它可以直接在「歐米茄」線進行更換:

import re 

for count in range(10): 

    # Reading: 
    with open('MRFzones') as input_file: # Automatically closes the file after reading 
     contents = input_file.read() # Whole file 

    # Writing: 
    with open('MRFzones', 'w') as out_file: 
     # The 'omega.*(\d+)' searches for a line with "omega" followed at some point by digits and ";". sub() performs 
     # a substitution of the part matched inside the parentheses: 
     out_file.write(re.sub('omega +(\d+);', str(count), contents, count=1)) # count=1 only modifies the first omega line 
+0

必須有'?'在''''*'之後'(\ d +);''',否則''(\ d +)'只會匹配最後一個數字的最後一位,也就是'1'數字將是'10'。順便說一句,我不明白爲什麼它應該是'''。*?'''而不是''+''',因爲在所需的數字之前沒有其他空格。 – eyquem 2011-05-02 15:03:37

+0

@eyquem:謝謝。我想我最初的意思是'*'(而不是''*')。 – EOL 2011-05-09 19:27:14

1

使用Python,你可以在一個文件中使用正則表達式和處理與模式「RB +」:

import re 
from time import sleep 

regx = re.compile('^ +omega +omega +\[[ \d.eE+-]+\] +(\d\d?)(;.+)',re.MULTILINE|re.DOTALL) 

for i in xrange(1,11): 
    sleep(20*60) 
    with open('MRFzones', 'rb+') as f: 
     m = regx.search(f.read()) 
     x = m.start(1) 
     f.seek(x,0) 
     f.writelines((str(i),m.group(2))) 
     f.tuncate() 

我假設初始文件是包含

'  omega omega [0 0 -1 0 0 0 0] 0;' 

是記錄匹配 在這些結果的結果MatchObject,叔這裏有:

  • 在文件的內容中的位置,其中開始由所述第一組中的匹配擦肩而過,1或2位(一個或多個)序列中,一個由(\d\d?)定義。該開始經由方法獲得開始()的稱爲用1作爲參數
  • 由第二組中的匹配釣到的文本中,(;.+)定義,由方法得到組()的稱爲用2作爲參數

re.MULTILINE使得在正則表達式匹配線的每個開始的圖案符號「^」,即每個'\n'後和在第精確字符串的開頭。如果沒有re.MULTILINE「^」意味着只能與字符串

re.DOTALL開頭的匹配,使點的模式匹配任何字符,包括新行。所以';.+'的意思是:字符';'以及後面的所有字符';'直到字符串的最後。如果沒有re.DOTALL,模式中的符號點將停止匹配該行的末尾。

執行f.read()後,文件的指針位於硬盤驅動器上文件的末尾。 seek()允許移動它。在這種情況下,seek(x,0)將指針移到一個位置,該位置位於從文件開頭起的x個字符(0表示'從開始',請參閱seek()以瞭解其他類型的移動)

執行f.seek(x,0)之後,指針位於要更改的整數之前。寫作str(i)刪除和寫在古代號碼。

f.truncate()是使文件在當前位置結束。在我的代碼中,它並不是絕對必需的,因爲被替換的字符串總是被長度相同或更長的字符串替換。

注意,此代碼可以如果存在對於其中可以寫入兩個字符的文件中的數保留的兩個位置被簡化:「0」,「1」,「2」,「3」,等

在這種情況下,代碼可以是:

​​

import re 
from time import sleep 

regx = re.compile('^ +omega +omega +\[[ \d.eE+-]+\] +(\d\d?)(;.+)',re.MULTILINE|re.DOTALL) 

with open('Copie de oso.txt', 'rb+') as f: 
    m = regx.search(f.read()) 
    x = m.start(1) 
    f.seek(x,0) 
    f.writelines((' 1',m.group(2))) 
    f.truncate() 

for i in xrange(2,11): 
    sleep(20) 
    with open('Copie de oso.txt', 'rb+') as f: 
     f.seek(x,0) 
     f.write('{:>2}'.format(i)) 

PS

括號'['']' 中的圖案的符號序列[ \d.eE+-]定義一組字符。我在這兩個括號之間放置了所有可能用於編寫數字的字符。重要的是,' - '將在該集合的末尾,否則這將意味着另一個事物,即只是' - '字符。

'\[''\]'和是轉義括號來表示只是字符「括號」,而不是限定的一組

我選用趕上符號括號「[0 0 -1 0 0 0 0]」與萬一圖案,該號碼可以是任何其它種類的數目的部分\[[ \d.eE+-]+\],在任何類型的表示的(由指數表示法)表示

' +'在圖案的意思是「任意數量的毛坯」

相關問題