[英]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.