任务
我正在用python编写一个程序,通过每次将一个新的.s2k文件导入SAP2000程序来运行SAP2000程序,然后通过导出数据的方式从上次运行的结果中生成一个新文件。
该文件大约有1500行,包含任意单词和数字。(为了更好地理解,请参阅:http://pastebin.com/8ptYacJz,这是我正在处理的文件。)
我被要求替换文件中的一个数字。这个数字在800行中间的某个地方。
问题
有人知道一种有效的方法可以将文件中的第800行移到中间,以替换一个数字吗?
我尝试了什么
正则表达式不起作用,因为同一数字可能有多个实例。
因此,我提出了一个解决方案,即对文件进行模板化,每次都编写一个新文件,并将要更改的数字作为模板参数。
这个解决方案确实有效,但该人员坚持认为我可以将文件指针向下移动到第800行,然后移动到该行的中间以替换数字。
这是我唯一能解决这个问题的代码,当我试图重新查找时,它会将文件缓冲区移到一行,然后返回到开头。
import sys
import os
#open file
f = open("output.$2k")
#this will go to line 883 in text file
count = 0;
while count < 883:
line = f.readline()
count = count+1
#this would seek over to middle of file DOESN'T WORK
f.seek(0,0)
line = f.readline()
print(line)
f.close()
是和否考虑:
f=open('output.$2k','r+')
f.seek(300)
f.write('n')
f.close()
这个脚本只是将ascii文件中的第300个字符更改为换行符。现在,棘手的部分是,在找到换行符之前,除了读取之外,没有办法知道ascii文件中一行的长度。因此,将文件中的特定字符定位在第800行的中间是非常重要的。但是,如果您能够保证(由于文件的编写方式)行长度,则可以毫无问题地计算位置。还要注意,用100
替换1
在这里不起作用。您需要将1个字符替换为1个字符。
只为世界上所有其他*NIX用户。。。请不要将$
放在文件名中。那只是一场噩梦。。。
好吧,我不是专业的程序员,但我(愚蠢的)方法是:如果总是第800行,那么在跟踪行号的同时逐行读取文件。然后直接写入一个新文件。读第800行,改一改,写一写。然后写剩下的。愚蠢而不优雅,但除非我错过了我可能会做的事情,否则它应该会起作用。还有我微薄的名声:D
否。读入该行,对其进行操作,然后将其写入到您之前打开的要写入的新文件中(并且一直在写入其他行,未修改)。
第一件事:
#this would seek over to middle of file DOESN'T WORK
f.seek(0,0)
这不是真的。这是为了找到文件的开头。
对于您的实际问题:
有人知道一种有效的方法可以将文件中的第800行移到中间,以替换一个数字吗?
一般来说,不会。你需要重写文件。例如:
# open the file in read-and-update mode
with open("file", 'r+') as f:
# read all lines
lines = f.readlines()
# update 800'th line
my_line = lines[799].split()
my_line[5] = "%s" % my_number # TODO: put in index of number and updated number
lines[799] = " ".join(my_line)
# truncate and rewrite file
f.truncate(0)
f.writelines(lines)
如果数字在文件中的起始位置是可预测的(例如文件开头的number_starting_pos = 1234
),并且字符串表示的大小也是可预测的,则可以执行此操作(例如20
)。然后,您可以重写数字,并确保再次用空格填充填充,以覆盖上一条的任何内容。类似于此:
with open("file", 'r+') as f:
# seek to the number starting position
f.seek(number_starting_pos, 0)
# update number field, assuming width (20), arbitrary space-padding allowed
my_number_string = "%19s " % my_number
# make sure the string is indeed exactly of the specific size (it may be longer)
assert len(my_number_string) == 20, "file writing would fail! aborting!"
f.write(my_number_string)
要做到这一点,您需要查看SAP的文档,看看空白是否真的无关紧要。
然而,这两种方法都是基于大量的假设。根据您的使用情况,它可能很容易破坏您的代码,例如,如果在数字字段之前插入一行,甚至插入一个字符。