如何从文本文件中提取信息

问题描述 投票:0回答:2

我有许多具有给定格式的文本文件(它不会逐行完全是这种格式;我将显示一个文件中的一些部分以了解一般格式)。

 C:\seismo\2008\07\2008-07-03-2055-56S.HP____030                      
  2008 7 3205556 BNJR  tc  16.1  f  1.5  s/n  4.0  Q  101  corr -0.89  rms 0.18
  2008 7 3205556 BNJR  tc  16.1  f  3.0  s/n  2.9  Q  290  corr -0.80  rms 0.20
  2008 7 3205556 BNJR  tc  16.1  f  8.0  s/n  3.9  Q  695  corr -0.63  rms 0.37
  2008 7 3205556 BNJR  tc  16.1  f 12.0  s/n  8.1  Q  913  corr -0.67  rms 0.39
  2008 7 3205556 BNJR  tc  16.1  f 16.0  s/n  5.7  Q 1435  corr -0.58  rms 0.42
 C:\seismo\2008\07\2008-07-03-2055-56S.HP____030                      
  2008 7 3205556 BNJR  tc  16.1  f  1.5  s/n  7.9  Q  150  corr -0.78  rms 0.19
  2008 7 3205556 BNJR  tc  16.1  f  3.0  s/n  5.3  Q  190  corr -0.86  rms 0.24
  2008 7 3205556 BNJR  tc  16.1  f  5.0  s/n  2.3  Q  401  corr -0.64  rms 0.39
  2008 7 3205556 BNJR  tc  16.1  f  8.0  s/n  3.1  Q  673  corr -0.65  rms 0.37
  2008 7 3205556 BNJR  tc  16.1  f 16.0  s/n  3.8  Q 1320  corr -0.64  rms 0.39
 C:\seismo\2008\07\2008-07-24-1124-44S.HP____012                      
 C:\seismo\2008\07\2008-07-24-1124-44S.HP____012                      
  2008 724112444 BNJR  tc   9.3  f  1.5  s/n  2.7  Q  119  corr -0.82  rms 0.21
  2008 724112444 BNJR  tc   9.3  f  3.0  s/n  2.3  Q  286  corr -0.68  rms 0.29
 C:\seismo\2008-10-21-1507-30S.__053                                    
 C:\seismo\2008-10-21-1544-56S.__033                                    
 C:\seismo\2008-10-21-1544-56S.__033                                    
 C:\seismo\2008-10-21-1544-56S.__033                                    
 C:\seismo\2008-10-21-1742-39S.NSN___015                                    
 C:\seismo\2008-10-21-1742-39S.NSN___015 
 C:\seismo\2010-11-18-1111-12S.NSN___027                                    
  20101118111112 BNJR  tc  20.2  f  1.5  s/n  2.6  Q  141  corr -0.79  rms 0.20
  20101118111112 BNJR  tc  20.2  f  3.0  s/n  6.6  Q  292  corr -0.58  rms 0.37
  20101118111112 BNJR  tc  20.2  f  5.0  s/n  3.4  Q  894  corr -0.54  rms 0.23
 C:\seismo\2011-02-01-2130-40S.NSN___027                                    
 C:\seismo\2011-02-04-0333-36S.NSN___027                                    
 C:\seismo\2011-02-04-0333-36S.NSN___027    

显示某些文件的文件路径及其内容,如果文件没有所需内容,则仅显示文件的路径。 enter image description here

我用红色矩形标记的信息(变量)是我要搜索的关键信息,无论该文件是否在上面的文件中列出。如果列出了,则内容也需要提取。 我正在寻找一种方法来提取文件中显示的路径及其内容(与我所拥有的信息相对应)(红色矩形)。在提取内容时,我想专门提取标有黑色矩形的列。

我制作了一个函数来提取相对于包含特定字符串的行的行/多行。由于每个路径后面的内容具有不同的行数,因此这个函数在我的问题中似乎毫无用处。

def extract_lines(file,linenumbers,endline=None):
    '''Extract a line /multiple lines from a text file
    line number should be considered as starting from zero.    
    '''
    
    with open(file, encoding='utf8') as f:
        content = f.readlines()                  
    lines=[]     
    if ((type(linenumbers) is int) or (all([isinstance(item, int) for item in linenumbers]))):
        
        if type(linenumbers) is list:
            for idx,item in enumerate(linenumbers):
                lines.append(content[item])
                
        elif ((endline is None) and (type(linenumbers) is int)):
            lines.append(content[linenumbers])
        
        elif ((type(endline) is int) and (type(linenumbers) is int)):
            for item in np.arange(linenumbers,endline):
                lines.append(content[item])                   
        else:
            print('Error in linenumbers input')
            
    lines=[s.replace('\t',' ') for s in lines]
    lines=[s.strip('\n') for s in lines]            
    return lines

如何使用 python 执行此任务?

python python-3.x pandas numpy text
2个回答
1
投票

此文件具有固定列,因此您需要使用列号来获取数据。

#0123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-
#  2008 7 3205556 BNJR  tc  16.1  f  1.5  s/n  4.0  Q  101  corr -0.89  rms 0.18

for ln in open('x.txt'):
    # Is this a file line or a data line?
    if ln[1] != ' ':
        curfile = ln.strip()
    else:
        # Grab date and time.
        dt = ln[2:14].replace(' ','0')
        # Grab the 2-digit code.
        dc = ln[14:16]
        # Grab site code
        site = ln[17:21]
        # Grab the 'f' code.
        f = float(ln[34:39].strip())
        # Grab the 'Q' code.
        q = int(ln[52:56].strip())

        print(f"{dt},{dc},{site},{f},{q}")

输出:

200807032055,56,BNJR,1.5,10
200807032055,56,BNJR,3.0,29
200807032055,56,BNJR,8.0,69
200807032055,56,BNJR,12.0,91
200807032055,56,BNJR,16.0,143
200807032055,56,BNJR,1.5,15
200807032055,56,BNJR,3.0,19
200807032055,56,BNJR,5.0,40
200807032055,56,BNJR,8.0,67
200807032055,56,BNJR,16.0,132
200807241124,44,BNJR,1.5,11
200807241124,44,BNJR,3.0,28
201011181111,12,BNJR,1.5,14
201011181111,12,BNJR,3.0,29
201011181111,12,BNJR,5.0,89

0
投票

从发布的数据中很难看出,但我认为这是制表符分隔的数据。第一列要么有文件名,要么为空。您想要将没有文件名的数据与其上方的文件名分组。

itertools.groupby
可以做到这一点。让它在每个非空的第一列上开始一个新组。请注意,您也可以在 pandas 中使用其
read_csv
及其
groupby
方法来执行此操作。

在示例中,我将 groupby 代码放入生成器函数中。这使得它可以在多个地方使用并减少嵌套。或者,您可以将

yield
替换为您自己的代码并跳过额外的函数。

import itertools
import csv

def extract_records(filename):
    """Yield (filename, list_of_rows) pairs from file"""
    found_filename = None
    with open(filename, encoding="utf8", newline="") as file:
        reader = csv.reader(file, dialect="excel-tab")
        for is_filename, rows in itertools.groupby(reader,
                lambda row: not row[0].strip()):
            if is_filename:
                found_filename = list(rows)[0][0] # only row, first column
            else:
                assert found_filename is not None, "filename precedes values"
                yield found_filename, list(rows)

for filename, values in extract_records("test.txt"):
    print(filename, values)
© www.soinside.com 2019 - 2024. All rights reserved.