在文本中更改两行

时间:2012-06-29 21:50:54

标签: python file-io editing

到目前为止,我有一个python脚本,主要用于我正在进行的项目,并且遇到了障碍。我基本上运行一个程序,吐出以下输出文件(称为big.dmp):

)O+_05 Big-body initial data  (WARNING: Do not delete this line!!)
) Lines beginning with `)' are ignored.
)---------------------------------------------------------------------
  style (Cartesian, Asteroidal, Cometary) = Cartesian
  epoch (in days) =    1365250.
)---------------------------------------------------------------------
COMPSTAR r=5.00000E-01 d=3.00000E+00  m= 0.160000000000000E+01
  4.570923967127310E-01  1.841433531828977E+01  0.000000000000000E+00
 -6.207379670518027E-03  1.540861575481520E-04  0.000000000000000E+00
  0.000000000000000E+00  0.000000000000000E+00  0.000000000000000E+00

现在有了这个文件,我需要编辑epoch行和以COMPSTAR开头的行,同时保持其余的信息从集成到集成不变,因为最后3行包含我的对象的笛卡尔坐标,基本上是程序正在输出。

我知道如何使用f = open('big.dmp', 'w')f.write('text here')创建初始文件但是如何将这些最后三行读入新的big.dmp文件以进行下一次集成?

4 个答案:

答案 0 :(得分:1)

或许这样的事情?

infile = open('big1.dmp')
outfile = open('big2.dmp', 'w')

for line in infile:
    if line.startswith(')'):
        # ignore comments
        pass
    elif 'epoch' in line:
        # do something with line
        line = line.replace('epoch', 'EPOCH')
    elif line.startswith('COMPSTAR'):
        # do something with line
        line = line.replace('COMPSTAR', 'comparison star')
    outfile.write(line)

答案 1 :(得分:1)

如果您的文件的格式是关于行号的格式的可能性,此解决方案将只更改两行:

with open('big.dmp') as inf, open('out.txt', 'w') as outf:
    data = inf.readlines()
    data[4] = '  epoch (in days) = 9999.\n'      # line with epoch
    data[6] = 'COMPSTAR r=2201 d=3330  m= 12\n'  # line with COMPSTAR
    outf.writelines(data)

生成此输出文件:

)O+_05 Big-body initial data  (WARNING: Do not delete this line!!)
) Lines beginning with `)' are ignored.
)---------------------------------------------------------------------
  style (Cartesian, Asteroidal, Cometary) = Cartesian
  epoch (in days) = 9999.
)---------------------------------------------------------------------
COMPSTAR r=2201 d=3330  m= 12
  4.570923967127310E-01  1.841433531828977E+01  0.000000000000000E+00
 -6.207379670518027E-03  1.540861575481520E-04  0.000000000000000E+00
  0.000000000000000E+00  0.000000000000000E+00  0.000000000000000E+00

显然,如果行号不一致,这将工作,但我想我会提供它,以防万一你的数据格式在行号方面是一致的。

此外,由于它一次将整个文件读入内存,因此对于真正庞大的文件来说,它不是理想的解决方案。

使用with打开文件的好处是,当您完成这些文件或遇到异常时,它们会自动关闭。

有更灵活的解决方案(搜索字符串,逐行处理文件)但如果您的数据是固定的和小的,那么利用这些因素没有任何缺点。聪明的人曾经说过“简单比复杂更好”。 (Python的禅宗)

答案 2 :(得分:1)

这是一个更容易改变的版本:

import re

reg_num = r'\d+'
reg_sci = r'[-+]?\d*\.?\d+([eE][+-]?\d+)?'

def update_config(s, finds=None, replaces=None, **kwargs):
    if finds is None:    finds = update_config.finds
    if replaces is None: replaces = update_config.replaces

    for name,value in kwargs.iteritems():
        s = re.sub(finds[name], replaces[name].format(value), s)
    return s

update_config.finds = {
    'epoch': r'epoch \(in days\) =\s*'+reg_num+'\.',
    'r':     r' r\s*=\s*' + reg_sci,
    'd':     r' d\s*=\s*' + reg_sci,
    'm':     r' m\s*=\s*' + reg_sci
}
update_config.replaces = {
    'epoch': 'epoch (in days) ={:>11d}.',
    'r':     ' r={:1.5E}',
    'd':     ' d={:1.5E}',
    'm':     ' m= {:1.15E}'
}

def main():
    with open('big.dmp') as inf:
        s = inf.read()

    s = update_config(s, epoch=1365252, r=0.51, d=2.99, m=1.1)

    with open('big.dmp', 'w') as outf:
        outf.write(s)

if __name__=="__main__":
    main()

答案 3 :(得分:0)

有点难以理解你想要的东西,但假设你只想删除不以开头的行:)

text = open(filename).read()
lines = text.split("\n")
result = [line for line in lines if not line.startswith(")")

或者,一个班轮:

[line for line in open(file_name).read().split("\n") if not line.startswith(")")]