python搜索文件中的字符串返回整行+;新文本文件的下一行

python搜索文件中的字符串返回整行+;新文本文件的下一行,python,string,file,search,memory,Python,String,File,Search,Memory,我有一个非常大的文本文件(50000多行),它应该始终处于相同的顺序。在python中,我想在文本文件中搜索每一行$INGGA,并将这一行与后面的$INHDT连接起来,以创建一个新的文本文件。我需要在不读取内存的情况下执行此操作,因为这会导致它每次崩溃。我可以找到返回$INGGA行的方法,但我不确定获得下一行并加入一个新字符串的最佳方法是什么,这样可以节省内存 谢谢 菲尔 =~=~=~=~=~=~=~=~=~=~=~=~=~=~=油灰日志2016.05.06 09:11:34=~=~=~=~=~

我有一个非常大的文本文件(50000多行),它应该始终处于相同的顺序。在python中,我想在文本文件中搜索每一行$INGGA,并将这一行与后面的$INHDT连接起来,以创建一个新的文本文件。我需要在不读取内存的情况下执行此操作,因为这会导致它每次崩溃。我可以找到返回$INGGA行的方法,但我不确定获得下一行并加入一个新字符串的最佳方法是什么,这样可以节省内存

谢谢

菲尔

=~=~=~=~=~=~=~=~=~=~=~=~=~=~=油灰日志2016.05.06 09:11:34=~=~=~=~=~=~=~=~=~=~=>$PRDID,2.15,-0.10,31.87*6E $INGGA,091124.005249.8336,北,00120.9619,西,1,20,0.6,95.0,米,49.4,米,*50 $INHDT,31.9,T*1E$INZDA,091124.0055,06,052016,,*7F $INVTG,22.0,T,,M,4.4,N,8.1,K,A*24$PRDID,2.13,-0.06,34.09*6C $INGGA,091124.205249.8338,北,00120.9618,西,1,20,0.6,95.0,米,49.4,米,*5D $INHDT,34.1,T*13$INZDA,091124.2055,06,052016,,*7D $INVTG,24.9,T,,M,4.4,N,8.1,K,A*2B$PRDID,2.16,-0.03,36.24*61 $INGGA,091124.405249.8340,北,00120.9616,西,1,20,0.6,95.0,米,49.4,米,*5A $INHDT,36.3,T*13$INZDA,091124.4055,06,052016,,*7B $INVTG,27.3,T,,M,4.4,N,8.1,K,A*22$PRDID,2.11,-0.05,38.33*68 $INGGA,091124.605249.8343,北,00120.9614,西,1,20,0.6,95.1,米,49.4,米,,*58 $INHDT,38.4,T*1A$INZDA,091124.6055,06,052016,,*79 $INVTG,29.5,T,,M,4.4,N,8.1,K,A*2A$PRDID,2.09,-0.02,40.37*6D $INGGA,091124.805249.8345,北,00120.9612,西,1,20,0.6,95.1,米,49.4,米,,*56 $INHDT,40.4,T*15$INZDA,091124.8055,06,052016,,*77 $INVTG,31.7,T,M,4.4,N,8.1,K,A*21$PRDID,2.09,0.02,42.42*40 $INGGA,091125.005249.8347,北,00120.9610,西,1,20,0.6,95.1,米,49.4,米,*5F 每小时42.4美元,T*17


您可以只读取一行文件,然后写入另一个新文件。 像这样:

import re

#open new file with append
nf = open('newfile', 'at')

#open file with read 
with open('file', 'rt') as f:
    for line in f:
        r = re.match(r'\$INGGA', line)
        if r is not None:
            nf.write(line)
            nf.write("$INHDT,31.9,T*1E" + '\n')
您可以使用
at
追加写入,使用
wt
追加读取行


我有150000行文件,运行良好

您只需读取一行文件并写入另一个新文件即可。 像这样:

import re

#open new file with append
nf = open('newfile', 'at')

#open file with read 
with open('file', 'rt') as f:
    for line in f:
        r = re.match(r'\$INGGA', line)
        if r is not None:
            nf.write(line)
            nf.write("$INHDT,31.9,T*1E" + '\n')
您可以使用
at
追加写入,使用
wt
追加读取行


我有150000行文件,运行良好

我建议使用一个简单的正则表达式来解析和捕获您关心的部分。下面是一个示例,它将捕获您所关心的部分:

(\$INGGA.*\n\$INHDT.*\n)

在我上面的链接中,您会注意到我在regex上使用了“global”g设置,告诉它捕获所有匹配的组。否则,它将在第一场比赛后停止

我也很难确定在上面的示例文件中实际的换行符存在于何处,因此您可以调整上面的内容以精确匹配换行符出现的位置

下面是一些初学者python示例代码:

import re

test_str = # load your file here

p = re.compile(ur'(\$INGGA.*\n\$INHDT.*\n)')
matches = re.findall(p, test_str)

我建议使用一个简单的正则表达式来解析和捕获您关心的部分。下面是一个示例,它将捕获您所关心的部分:

(\$INGGA.*\n\$INHDT.*\n)

在我上面的链接中,您会注意到我在regex上使用了“global”g设置,告诉它捕获所有匹配的组。否则,它将在第一场比赛后停止

我也很难确定在上面的示例文件中实际的换行符存在于何处,因此您可以调整上面的内容以精确匹配换行符出现的位置

下面是一些初学者python示例代码:

import re

test_str = # load your file here

p = re.compile(ur'(\$INGGA.*\n\$INHDT.*\n)')
matches = re.findall(p, test_str)

在您给出的示例PuTTY log中,所有的一行都用空格分隔。 在这种情况下,你可以用新行替换空格,得到新文件-

cat large_file | sed 's/ /\n/g' > new_large_file
要迭代使用新行分隔的文件,请运行以下命令-

cat new_large_file | python your_script.py
您的脚本将逐行获取,这样您的计算机就不会崩溃

您的_script.py-

import sys

INGGA_line = ""

for line in sys.stdin:
    line_striped = line.strip()
    if line_striped.startswith("$INGGA"):
        INGGA_line = line_striped
    elif line_striped.startswith("$INZDA"):
        print line_striped, INGGA_line
    else:
        print line_striped

在您给出的示例PuTTY log中,所有的一行都用空格分隔。 在这种情况下,你可以用新行替换空格,得到新文件-

cat large_file | sed 's/ /\n/g' > new_large_file
要迭代使用新行分隔的文件,请运行以下命令-

cat new_large_file | python your_script.py
您的脚本将逐行获取,这样您的计算机就不会崩溃

您的_script.py-

import sys

INGGA_line = ""

for line in sys.stdin:
    line_striped = line.strip()
    if line_striped.startswith("$INGGA"):
        INGGA_line = line_striped
    elif line_striped.startswith("$INZDA"):
        print line_striped, INGGA_line
    else:
        print line_striped

这个答案是针对Python3的

根据(和),您可以高效地逐行迭代文件内存:

with open(filename, 'r') as f:
    for line in f:
         ...process...
您如何满足上述标准的示例可以是

# Target file write-only, source file read-only
with open(targetfile, 'w') as tf, open(sourcefile, 'r') as sf:
    # Flag for whether we are looking for 1st or 2nd part
    look_for_ingga = True
    for line in sf:
        if look_for_ingga:
            if line.startswith('$INGGA,'):
                tf.write(line)
                look_for_ingga = False
        elif line.startswith('$INHDT,'):
            tf.write(line)
            look_for_ingga = True
  • 如果在
    '$INHDT'
    之前有多个
    '$INGGA'
    ,则会抓住第一个并忽略其余部分。如果您只想在
    '$INHDT'
    之前获取最后一个
    '$INGGA'
    ,请将最后一个
    '$INGGA'
    存储在变量中,而不是将其写入磁盘。然后,当您找到您的
    “$INHDT”
    时,将两者都存储起来
  • 如果您的意思是要为每个INGGA-INHDT对写入一个单独的新文件,那么目标文件
    with
    -语句应该嵌套在sf行的
    中,或者结果应该缓存在列表中以备以后存储

有关和的介绍,请参阅文档。

此答案针对的是python 3

根据(和),您可以高效地逐行迭代文件内存:

with open(filename, 'r') as f:
    for line in f:
         ...process...
您如何满足上述标准的示例可以是

# Target file write-only, source file read-only
with open(targetfile, 'w') as tf, open(sourcefile, 'r') as sf:
    # Flag for whether we are looking for 1st or 2nd part
    look_for_ingga = True
    for line in sf:
        if look_for_ingga:
            if line.startswith('$INGGA,'):
                tf.write(line)
                look_for_ingga = False
        elif line.startswith('$INHDT,'):
            tf.write(line)
            look_for_ingga = True
  • 如果在
    '$INHDT'
    之前有多个
    '$INGGA'
    ,则会抓住第一个并忽略其余部分。如果您只想在
    '$INHDT'
    之前获取最后一个
    '$INGGA'
    ,请将最后一个
    '$INGGA'
    存储在变量中,而不是将其写入磁盘。然后,当您找到您的
    “$INHDT”
    时,将两者都存储起来
  • 如果您的意思是要为每个INGGA-INHDT对写入一个单独的新文件,那么目标文件
    with
    -语句应该嵌套在sf
    行的
    中,或者结果应该缓存在列表中以备以后存储
有关和的介绍,请参阅文档。

请回答您的问题,并包括您尝试过的内容。有效吗?你能详细说明一下吗