根据文本文件的内容拆分文本文件

时间:2016-12-12 21:15:50

标签: python file parsing text split

我有一个看起来像这样的文本文件:

SYSTEM

DOF=UY,UZ,RX  LENGTH=FT  FORCE=Kip

JOINT
  1  X=0  Y=-132.644  Z=0
  2  X=0  Y=-80  Z=0
  3  X=0  Y=-40  Z=0
  4  X=0  Y=0  Z=0
  5  X=0  Y=40  Z=0
  6  X=0  Y=80  Z=0
  7  X=0  Y=132.644  Z=0

等。对于10,000个关节。

我想编写一个脚本来读取此文本文件并输出4个文本文件,每个文本文件包含1个列,每个包含联合编号,x坐标,y坐标和z坐标。

这可能吗?我是python的新手,尝试过类似的东西,但Python不知道如何处理文本文件中的System,我确定我的方法不正确:

os.chdir('/Users/DevEnv/')

with open('RawDataFile_445.txt') as a:
    for line in a.readlines():
        j=[]
        data=line.strip()
        data1=data.split(" ")
        for i in range(0,len(data1)):
            j.append(eval(data1[i]))
        joint=j

2 个答案:

答案 0 :(得分:2)

你的解决方案似乎很脆弱:

  • 您必须过滤标题,非数据行
  • 你使用eval(),这实在是太过分和不安全了。
  • 使用readlines()可能会非常耗费内存:读取内存中的所有数据,您不需要这样做。一次只读一行。
  • 您错过了写回输出文件的代码

我的解决方案使用正则表达式一次性提取所有数据。代码中的评论:

import re

# regex to extract data line    
r = re.compile(r"\s*(\d+)\s+X=(\S+)\s+Y=(\S+)\s+Z=(\S+)")

with open('RawDataFile_445.txt') as a:

    # open all 4 files with a meaningful name
    files=[open("file_{}.txt".format(x),"w") for x in ["J","X","Y","Z"]]
    for line in a:
        m = r.match(line)
        if m:
            # line matches: write in all 4 files (using zip to avoid doing
            # it one by one)
            for f,v in zip(files,m.groups()):
                f.write(v+"\n")

    # close all output files now that it's done
    for f in files:
        f.close()

您可以将with open(...) as a:位替换为:

来测试它
a="""SYSTEM

DOF=UY,UZ,RX  LENGTH=FT  FORCE=Kip

JOINT
  1  X=0  Y=-132.644  Z=0
  2  X=0  Y=-80  Z=0
  3  X=0  Y=-40  Z=0
  4  X=0  Y=0  Z=0
  5  X=0  Y=40  Z=0
  6  X=0  Y=80  Z=0
  7  X=0  Y=132.644  Z=0""".splitlines().__iter__()

模拟输入文件行(这是我如何回答输入文件的问题,以避免在我的系统上创建输入文件)。您将看到4个文件已创建并已填满(请勿忘记代码末尾的close部分)

答案 1 :(得分:0)

尝试:

xlist, ylist, zlist = [], [], []
for line in file.readlines():
    try:
        if line.strip()[0].isdigit():
                s = line.split("=")
                x, y, z = (float(s[i][:-1].strip()) for i in range(1, 4))
                xlist.append(x)
                ylist.append(y)
                zlist.append(z)
    except:
        pass

这将为以数字开头的每一行执行此操作。注意:如果没有空行,则不需要try语句。