我有许多具有给定格式的文本文件(它不会逐行完全是这种格式;我将显示一个文件中的一些部分以了解一般格式)。
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
显示某些文件的文件路径及其内容,如果文件没有所需内容,则仅显示文件的路径。
我用红色矩形标记的信息(变量)是我要搜索的关键信息,无论该文件是否在上面的文件中列出。如果列出了,则内容也需要提取。 我正在寻找一种方法来提取文件中显示的路径及其内容(与我所拥有的信息相对应)(红色矩形)。在提取内容时,我想专门提取标有黑色矩形的列。
我制作了一个函数来提取相对于包含特定字符串的行的行/多行。由于每个路径后面的内容具有不同的行数,因此这个函数在我的问题中似乎毫无用处。
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 执行此任务?
此文件具有固定列,因此您需要使用列号来获取数据。
#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
从发布的数据中很难看出,但我认为这是制表符分隔的数据。第一列要么有文件名,要么为空。您想要将没有文件名的数据与其上方的文件名分组。
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)