1

我正在尝试更改文本文件中的某些行而不影响其他行。这是名为“text.txt”的文本文件中的内容

this is  a test1|number1
this is a test2|number2
this is a test3|number2
this is a test4|number3
this is a test5|number3
this is a test6|number4
this is a test7|number5
this is a test8|number5
this is a test9|number5
this is a test10|number5

我的目标是更改第 4 行和第 5 行,但其余部分保持不变。

mylist1=[]
for lines in open('test','r'):
    a=lines.split('|')
    b=a[1].strip()
    if b== 'number3':
        mylist1.append('{}|{} \n'.format('this is replacement','number7'))
    else:
         mylist1.append('{}|{} \n'.format(a[0],a[1].strip()))
myfile=open('test','w')
myfile.writelines(mylist1)

即使代码有效,我想知道是否有更好和有效的方法来做到这一点?是否可以仅按行号读取文件?

4

5 回答 5

10

没有什么可以改进的。但是您必须将所有行写入一个新文件,无论是更改还是不变。小的改进是:

  • 使用with语句;
  • 避免在列表中存储行;
  • lines在子句中不带格式的书写else(如果适用)。

应用以上所有内容:

import shutil
with open('test') as old, open('newtest', 'w') as new:
    for line in old:
        if line.rsplit('|', 1)[-1].strip() == 'number3':
            new.write('this is replacement|number7\n')
        else:
            new.write(line)
shutil.move('newtest', 'test')
于 2013-05-17T08:45:34.137 回答
3
import fileinput

for lines in fileinput.input('test', inplace=True):
    # inplace=True redirects stdout to a temp file which will
    # be renamed to the original when we reach the end of the file. this
    # is more efficient because it doesn't save the whole file into memeory
    a = lines.split('|')
    b = a[1].strip()
    if b == 'number3':
        print '{}|{} '.format('this is replacement', 'number7')
    else:
        print '{}|{} '.format(a[0], a[1].strip())
于 2013-05-17T08:46:33.360 回答
2

不。文件是面向字节的,而不是面向行的,并且更改行的长度不会使后面的字节前进。

于 2013-05-17T08:44:21.237 回答
0

试试这个解决方案

with open('test', inplace=True) as text_file:
    for line in text_file:
         if line.rsplit('|', 1)[-1].strip() == 'number3':
             print '{}|{} \n'.format('this is replacement', 'number7')
         else:
             print line
于 2013-05-17T08:54:04.487 回答
0

您的意图是用它们的值还是用它们的行号来识别要替换的行,这并不完全清楚。

如果前者是你的意图,你可以得到这样的行列表:

with open('test','r') as f:
    oldlines = f.read().splitlines()

如果存在尾随空格的危险,您还可以:

然后你可以像这样处理它们:

newlines = [ line if not line.strip().endswith('|number3') else 'this is replacement|number7' for line in oldlines]

打开目标文件(我假设您要覆盖原始文件,在这里),并写下所有行:

with open('test','w') as f:
    f.write("\n".join(newlines))

这是一种通用模式,可用于任何类型的简单线路过滤。

如果您打算按数字识别行,则可以更改“换行符”行:

 newlines = [ line if i not in (3, 4) else 'this is replacement|number7' for i, line in enumerate(oldlines)]
于 2013-05-17T09:23:47.837 回答