3

我想找到一个更好的解决方案来实现以下三个步骤:

  1. 读取给定行的字符串
  2. 更新字符串
  3. 写回更新的字符串

下面是我的代码,但我想知道有没有更好(简单)的解决方案?

new='99999'

f=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP','r+')
lines=f.readlines()
#the row number we want to update is given, so just load the content
x = lines[95]
print(x)
f.close()


#replace
f1=open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP')
con = f1.read()
print con
con1 = con.replace(x[2:8],new) #only certain columns in this row needs to be updated
print con1
f1.close()


#write
f2 = open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'w')
f2.write(con1)
f2.close()

谢谢!更新:这次从 jtmoulia 那里得到一个想法变得更容易了

def replace_line(file_name, line_num, col_s, col_e, text):
    lines = open(file_name, 'r').readlines()
    temp=lines[line_num]
    temp = temp.replace(temp[col_s:col_e],text)
    lines[line_num]=temp
    out = open(file_name, 'w')
    out.writelines(lines)
    out.close()
4

4 回答 4

3

文本数据的问题,即使是在表格中,字节偏移量也是不可预测的。例如,当用字符串表示数字时,每个数字都有一个字节,而当使用二进制(例如二进制补码)时,无论是小整数还是大整数,您总是需要四个或八个字节。

不过,如果您的文本格式足够严格,您可以通过替换字节而不改变文件大小来解决问题,您可以尝试使用标准mmap模块。有了它,您将能够将文件视为可变字节字符串并就地修改其中的部分内容,并让内核为您保存文件。

否则,其他任何答案都更适合该问题。

于 2012-05-23T00:06:40.857 回答
1

好吧,首先,您不需要每次都重新打开和读取文件。该r+模式允许您读取和写入给定文件。

也许像

with open('C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP', 'r+') as f:
    lines = f.readlines()
    #... Perform whatever replacement you'd like on lines
    f.seek(0)
    f.writelines(lines)

此外,在 python 中编辑文本文件中的特定行

于 2012-05-22T23:38:55.253 回答
0

当我不得不做类似的事情时(对于 Webmin 定制),我完全在 PERL 中完成,因为这是 Webmin 框架使用的,而且我发现它很容易。我假设(但不确定)在 Python 中有等价的东西。首先将整个文件一次全部读入内存(PERL 执行此操作的方法可能称为“slurp”)。(这种将整个文件保存在内存中而不仅仅是一行的想法过去没有什么意义(甚至是不可能的)。但是现在 RAM 太大了,这是唯一的出路。)然后使用split运算符将文件分成几行,并将每一行放在一个巨型数组的不同元素中。然后,您可以使用所需的行号作为数组的索引(记住数组索引通常以 0 开头)。最后,使用“正则表达式”处理来改变行的文本。然后更改另一行,另一行,另一行(或对同一行进行另一次更改)。完成后,使用join将数组中的所有行重新组合成一个巨大的字符串。然后写出整个修改过的文件。

虽然我手头没有完整的代码,但这里有一些 PERL 代码的大致片段,因此您可以明白我的意思:

our @filelines = ();
our $lineno = 43;
our $oldstring = 'foobar';
our $newstring = 'fee fie fo fum';
$filelines[$lineno-1] =~ s/$oldstring/$newstring/ig; 
# "ig" modifiers for case-insensitivity and possible multiple occurences in the line
# use different modifiers at the end of the s/// construct as needed
于 2012-05-22T23:49:31.653 回答
-1
FILENAME = 'C:/Users/th/Dropbox/com/MS1Ctt-P-temp.INP'
lines = list(open(FILENAME))
lines[95][2:8] = '99999'
open(FILENAME, 'w').write(''.join(lines))
于 2012-05-22T23:35:51.180 回答