说我的文件如下:
foo
bar
BeginObject
something
something
ObjectAlias NotMe
lines
more lines
BeginKeyframe 22 12
foo
bar default
foo default
bar default
EndKeyframe
EndObject
foo
bar
BeginObject
something
something
ObjectAlias HeyThere
lines
more lines
BeginKeyframe 43243 12
foo
bar default
foo default
bar default
foo default
bar default
foo default
bar
EndKeyframe
EndObject
我想要一行:
BeginKeyframe 43243 12
替换为:
BeginKeyframe 6 12
注意: 6是"默认"以及BeginKeyframe和EndKeyframe
我的第一个版本的python代码有一些交互问题。见here
感谢sloth和Skycc,一个改进的版本正在运行。见here
现在的适用是改进的代码使用re模块来实现,这不是我想要的,我更喜欢将原始文件逐行复制到新文件而不会覆盖原始文件。
所以我的问题是如何改进Skycc的代码?
objectlist = ['GoodMoring', 'GoodAfternoon']
with open('input.txt', 'r+') as f:
line = f.readline()
pos = f.tell()
found = False
while line:
found = found or any('ObjectAlias ' + objectname in line for objectname in objectlist)
if 'EndObject' in line:
found = False
if found and 'BeginKeyframe' in line:
sub_line = f.readline()
frames = 0
while not 'EndKeyframe' in sub_line:
if 'default' in sub_line:
frames += 1
sub_line = f.readline()
pos2 = f.tell()
f.seek(pos)
f.write(re.sub('\d+', str(frames), line, count=1))
f.seek(pos2)
pos = f.tell()
line = f.readline()
答案 0 :(得分:1)
完整代码:
interested_objects = ['HeyThere', 'anotherone',]
buff = []
obj_flag = False
keyframe_flag = False
with open('in') as f, open ('out', 'w') as of:
for line in f:
line = line.strip()
if line.startswith('ObjectAlias'):
assert not obj_flag
assert not keyframe_flag
if line.split()[1] in interested_objects:
obj_flag = True
if not obj_flag:
print >>of, line
continue
if 'EndObject' in line:
assert not keyframe_flag
obj_flag = False
if 'BeginKeyframe' in line:
assert not keyframe_flag
keyframe_flag = True
if keyframe_flag:
buff.append(line)
else:
print >>of, line
if 'EndKeyframe' in line:
parts = buff[0].split()
new_line = '{} {} {}'.format(parts[0], len(buff)-2, parts[2])
print >>of, new_line
print >>of, '\n'.join(buff[1:])
buff = []
keyframe_flag = False
答案 1 :(得分:0)
只需以'w'
模式打开input.txt以进行只读,然后打开另一个文件output.txt并使用seek
模式写入新文件。并且不需要tell
和objectlist = ['GoodMoring', 'GoodAfternoon']
with open('input.txt', 'r') as f, open('output.txt', 'w') as fo:
found = False
begin_frame = False
buffer = []
for line in f:
if line.startswith('ObjectAlias'):
found = any('ObjectAlias ' + objectname in line for objectname in objectlist)
elif line.startswith('EndObject'):
if found and begin_frame:
# modify and write all buffer into output file
buffer[0] = buffer[0].replace(buffer[0].split()[1], str(frames), 1)
for i in buffer:
fo.write(i)
buffer = [] # clear buffer
found = False
begin_frame = False
elif line.startswith('BeginKeyframe'):
begin_frame = True
frames = 0
if found and begin_frame:
buffer.append(line)
if 'default' in line:
frames += 1
else:
fo.write(line)
,只需在读取输入文件时逐行处理它。
一旦找到BeginKeyFrame,就会使用缓冲区来保留这些行。找到EndObject时将缓冲区释放到输出文件。
快速编辑如下代码,应该有效但可能不那么优雅和pythonic
{{1}}