Python 解析文本文件和逻辑方法
我在处理Python逻辑时遇到了一些困难。
我想请教一下,如何解决我在Python和数据解析方面遇到的问题。
我花了一些时间阅读Python的参考文档,并在这个网站上浏览,我明白有几种方法可以实现我想要的目标,而我选择了这条路。
我正在重新格式化一些由卫星硬件生成的数据文本文件,以便上传到MySQL数据库中。
这是原始数据:
TP N: 1
Frequency: 12288.635 Mhz
Symbol rate: 3000 KS
Polarization: Vertical
Spectrum: Inverted
Standard/Modulation: DVB-S2/QPSK
FEC: 1/2
RollOff: 0.20
Pilot: on
Coding mode: ACM/VCM
Short frame
Transport stream
Single input stream
RF-Level: -49 dBm
Signal/Noise: 6.3 dB
Carrier width: 3.600 Mhz
BitRate: 2.967 Mbit/s
上面的部分会针对卫星上的每个转发器TP N
重复出现。
我正在使用这个脚本来提取我需要的数据。
strings = ("Frequency", "Symbol", "Polar", "Mod", "FEC", "RF", "Signal", "Carrier", "BitRate")
sat_raw = open('/BLScan/reports/1520.txt', 'r')
sat_out = open('1520out.txt', 'w')
for line in sat_raw:
if any(s in line for s in strings):
for word in line.split():
if ':' in word:
sat_out.write(line.split(':')[-1])
sat_raw.close()
sat_out.close()
然后,输出的数据在发送到数据库之前会被格式化成这样:
12288.635 Mhz
3000 KS
Vertical
DVB-S2/QPSK
1/2
-49 dBm
6.3 dB
3.600 Mhz
2.967 Mbit/s
这个脚本运行得很好,但为了在MySQL上实现一些功能,我需要进一步修改它。
- 在第一行“频率”中,去掉小数点及其后面的三个数字和“MHz”。
- 去掉所有后面的单位,比如
KS
、dBm
、dB
、Mhz
、Mbit
。 - 将9个字段合并成一个用逗号分隔的字符串,这样每个转发器(每个文件大约有30个)就会在自己的一行上。
我不确定是继续在这个现有的脚本上添加功能(我现在卡在输出文件写入的地方),还是重新考虑我处理原始文件的方法。
2 个回答
1
import math
strings = ("Frequency", "Symbol", "Polar", "Mod", "FEC", "RF", "Signal", "Carrier", "BitRate")
files=['/BLScan/reports/1520.txt']
sat_out = open('1520out.txt', 'w')
combineOutput=[]
for myfile in files:
sat_raw = open(myfile, 'r')
singleOutput=[]
for line in sat_raw:
if any(s in line for s in strings):
marker=line.split(':')[1]
try:
data=str(int(math.floor(float(marker.split()[0]))))
except:
data=marker.split()[0]
singleOutput.append(data)
combineOutput.append(",".join(singleOutput))
for rec in combineOutput:
sat_out.write("%s\n"%rec)
sat_raw.close()
sat_out.close()
把你想要处理的所有文件都放到 files
这个列表里。程序会把每个文件的输出写成单独的一行,每个字段之间用逗号隔开。
1
我的解决方案比较简单,可能在一些特殊情况下不太好用,但这是一个不错的开始。
import re
import csv
strings = ("Frequency", "Symbol", "Polar", "Mod", "FEC", "RF", "Signal", "Carrier", "BitRate")
sat_raw = open('/BLScan/reports/1520.txt', 'r')
sat_out = open('1520out.txt', 'w')
csv_writer = csv.writer(sat_out)
csv_output = []
for line in sat_raw:
if any(s in line for s in strings):
try:
m = re.match(r'^.*:\s+(\S+)', line)
value = m.groups()[0]
# Attempt to convert to int, thus removing the decimal part
value = int(float(value))
except ValueError:
pass # Ignore conversion
except AttributeError:
pass # Ignore case when m is None (no match)
csv_output.append(value)
elif line.startswith('TP N'):
# Before we start a new set of values, write out the old set
if csv_output:
csv_writer.writerow(csv_output)
csv_output=[]
# If we reach the end of the file, don't miss the last set of values
if csv_output:
csv_writer.writerow(csv_output)
sat_raw.close()
sat_out.close()
讨论
- csv这个包可以帮助我们输出CSV格式的文件。
- re(正则表达式)模块可以帮助我们解析每一行,并从中提取出需要的值。
- 在这一行代码中,
value = int(...)
,我们试图把字符串类型的值转换成整数,这样就去掉了小数点和后面的数字。 - 当代码遇到以'TP N'开头的行时,这表示一组新的值开始了。我们会把旧的一组值写入CSV文件。