0

任务

我正在用python编写一个运行SAP2000程序的程序,每次将一个新的.s2k文件导入到Sap2000程序中,然后通过导出数据的方式从上次运行的结果生成一个新文件。

该文件大约有 1,500 行,包含任意单词和数字。(为了更好地理解,请参阅: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()
4

4 回答 4

1

好的,我不是专业程序员,但我的(愚蠢的)方法是:如果总是第 800 行,则在跟踪行号的同时逐行读取文件。然后直接写入新文件。读取第 800 行,更改它,写入它。然后写剩下的。愚蠢而不优雅,但它应该可以工作 - 除非我错过了我可能会做的事情。还有我微薄的名声:D

于 2012-07-16T19:01:32.540 回答
1

是和不是。考虑:

f=open('output.$2k','r+')
f.seek(300)
f.write('\n')
f.close()

该脚本只是将您的 ascii 文件中的第 300 个字符更改为换行符。现在棘手的部分是没有办法知道 ascii 文件中一行的长度,除非你读到换行符。因此,将文件中的特定字符定位在第 800 行的中间并非易事。但是,如果您可以对行长做出保证(由于文件的编写方式),则可以毫无问题地计算位置。另请注意,替换1100在这里不起作用。您需要用 1 个字符替换 1 个字符。

并且仅针对世界上所有其他 *NIX 用户......请不要$输入您的文件名。那只是一场噩梦……

于 2012-07-16T18:53:14.733 回答
0

不。读取该行,对其进行操作,然后将其写入您之前打开的新文件中写入(并且一直在写入其他行,未修改)。

于 2012-07-16T18:53:20.133 回答
0

第一件事:

#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-thingy 的文档,并查看空格是否确实无关紧要。


然而,这两种方法都基于很多假设。根据您的用例,它可能很容易破坏您的代码,例如,如果在数字字段之前插入了一行,甚至插入了一个字符。

于 2012-07-16T21:41:58.413 回答