每隔20分钟在python中编辑文件中的SPECIFIC字

时间:2011-05-02 08:21:45

标签: python

我想以特定的间隔(例如每30分钟)更改下面文件中的omega值。该文件在运行时由另一个程序使用。我想慢慢地将RPM值(线上的最后一个条目)从0-10斜坡上升。基本上,下面文件中的值“5”需要每30分钟以0-10的增量从0改变。

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。有人可以帮我实现吗?我可能没有正确的想法,所以我们可以在必要时从头开始编写代码。

谢谢, 苏雷什

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

您现在可以浏览旧文件,值5已被145取代。 我个人不同意Sven,Python对我来说是处理这种情况的完美语言。

答案 2 :(得分:1)

执行所需操作的规范方法确实是使用正则表达式模块(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

答案 3 :(得分: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;'

m 是记录匹配结果的MatchObject 在这些结果中,有:

  • 文件内容中的位置,其中开始由匹配中的第一个组捕获的1或2个数字序列,由(\d\d?)定义的序列。这个开始是通过 m start()方法获得的,以1作为参数调用
  • (;.+)定义的匹配中第二组捕获的文字,由 m m 的方法获得,以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)

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))

<强> PS

模式中符号序列[ \d.eE+-]的括号'['']'定义了一组字符。我在这两个括号之间放了很多可能用来写数字的字符。重要的是' - 在集合的末尾,否则它将意味着另一个只有' - 字符的东西。

'\[''\]'是转义括号,仅表示字符'括号',而不是定义集合的符号括号

我选择使用模式的\[[ \d.eE+-]+\]部分来捕获'[0 0 -1 0 0 0 0 0]',以防数字可以是任何其他类型的数字,以任何形式表示(包括指数表示法)

模式中的

' +'表示“任意数量的空白”