[英]Editing a SPECIFIC word in a file in python, every 20 mins
我想以特定的時間間隔更改下面文件中 omega 的值,比如每 30 分鍾一次。 該文件在運行時被另一個程序使用。 我想緩慢地將 RPM 值(行中的最后一個條目)從 0 增加到 10。 本質上,下面文件中的值“5”需要以每 30 分鍾 1 的增量從 0-10 變化。
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。 有人可以幫我實現這個嗎? 我什至可能沒有正確的想法,所以如果有必要我們可以從頭開始編寫代碼。
謝謝, 蘇雷什
您根本沒有修改data
- 您正在提取line
和word
並修改它們。 最后,您將原始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
您可以通過導入的fileinput
模塊和正則表達式的re
模塊來識別行及其組件:
>>> import re
>>> pattern = r'(\s*omega\s+omega\s+\[-?\d+ -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ -?\d+\]) (-?\d+);'
大括號用於捕獲模式,請查看re 模塊以了解更多信息(非常有用的 Python 模塊,做得很好並記錄在案)!
我們有了我們的模式,現在瀏覽我們的文件: print
用於直接寫入文件(不再打印到屏幕),標准 function 在for
循環結束時恢復正常(文件關閉)。
不要忘記刪除換行符以避免 output 文件中出現不需要的換行符(是的,這有點煩人:循環給出的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
您現在可以瀏覽舊文件,值5
已替換為145
。 我個人不同意 Sven 的觀點,Python 對我來說是處理這種情況的完美語言。
做你想做的事的規范方法確實是使用正則表達式模塊( re )。 它可以直接在“omega”行中執行替換:
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
使用 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;'
m是記錄匹配結果的MatchObject,這些結果中,有:
(\d\d?)
定義。 這個開始是通過以 1 作為參數調用的m的方法start()獲得的(;.+)
定義,由m的方法group()獲得,以 2 作為參數調用 re.MULTILINE使正則表達式模式中的符號'^'與每個行首匹配,即恰好在每個'\n'
之后和字符串的開頭。 如果沒有re.MULTILINE , '^'僅表示與字符串開頭的匹配
re.DOTALL使模式中的點與任何字符匹配,包括換行符。 所以';.+'
意思是:字符';' 以及“;”后面的所有字符直到字符串的最后。 如果沒有re.DOTALL ,模式中的符號點將在行尾停止匹配。
執行f.read()
后,文件的指針位於硬盤驅動器上文件的末尾。 seek()允許移動它。 在這種情況下, seek(x,0)
將指針移動到 position,它位於文件開頭的x 個字符處(0 表示“從頭開始”,請參閱 seek() 以了解其他類型的移動)
執行f.seek(x,0)
后,指針就在您要更改的 integer 之前。 寫入str(i)擦除並寫入古代數字。
f.truncate()
是使文件以當前 position 結尾。 就我的代碼而言,這不是絕對必要的,因為被替換的字符串總是被相同或更長長度的字符串替換。
.
請注意,如果在文件中為可以寫入兩個字符的數字保留兩個位置,則可以簡化此代碼:'0'、'1'、'2'、'3'等
在這種情況下,代碼可以是:
import re
from time import sleep
regx = re.compile('^ +omega +omega +\[[ \d.eE+-]+\] +(\d\d?)',re.MULTILINE)
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.write('{:>2}'.format(i))
或者
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))
.
附言
模式中符號序列[ \d.eE+-]
的括號'['和']'定義了一組字符。 我把所有可能用來寫數字的字符放在這兩個括號之間。 重要的是, '-'位於集合的末尾,否則它意味着另一個東西,只是'-'字符。
'\['
和'\]'
是轉義括號,僅表示字符“括號”,而不是定義集合的符號括號
我選擇用模式的\[[ \d.eE+-]+\]
部分來捕捉'[0 0 -1 0 0 0 0]'以防數字可能是任何其他類型的數字,以任何形式表示表示形式(包括指數符號)
模式中的' +'
表示“任意數量的空格”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.