固定长度记录

Posted

技术标签:

【中文标题】固定长度记录【英文标题】:Fixed Length Records 【发布时间】:2020-03-29 07:28:34 【问题描述】:

我正在介绍如何使用 python 编写脚本类。我没有编程经验,所以我只知道该课程所教的内容,主要是 for 和 while 循环、基本函数、列表/字典以及当前的正则表达式和文件处理。

我收到了一个我必须打开的文件 P。我必须搜索变量 F(名字)和 L(姓氏),然后将关联的生日切换到 F,将 L 切换到 B(生日)。

每个名字的长度为 16 个字符。每个姓氏长度为 16 个字符。每个生日长度为 8 个字符。因此,每条记录的长度正好是 40 个字符。

下面的代码是我迄今为止将文件放入二维列表的代码。然后我如何搜索列表以找到 F 和 L?找到F和L后,如何将生日切换到B?希望这一切都有意义。提前谢谢你。

import re
file = open (P, 'r')
data = file.read()

records = []
while len(data) > 0:
  record = []
  record.append(data[0:16])
  record.append(data[16:32])
  record.append(data[32:40])
  records.append(record)
  data = data[40:]

【问题讨论】:

你能提供一个你得到的文本文件的例子吗? 看起来您有一个程序可以满足您的所有需求。您需要什么帮助? @user1558604 他正在寻找append(B) 到正确的name([F + L]) @CanadianCaleb,但他有一个 2D 列表 (records),类似于 [[F,L,B],[F,L,B]...]。至少我是这样理解的。如果他在寻找F+L+B,那么就是这40个字符加起来。 @user1558604 是的,我不太清楚它是怎么回事,这就是为什么我要一个例子。 【参考方案1】:

我假设“切换与 F 和 L 关联的生日”是指“获取 F 和 L 的生日”

您已经在表单中创建了一个列表列表:

[
 [F1, L1, B1],
 [F2, L2, B2],
 [F3, L3, B3],
 [F4, L4, B4]
]

您必须遍历第一个列表,并比较记录的第一个和第二个元素以匹配您想要的 F 和 L:

for r in records:
  if r[0] == F and r[1] == L:  # List indices starts from 0
    return r[2]

如果您不在函数内部,则不能return,因此需要时break

【讨论】:

这很有帮助。但我必须将文件中当前的 B 切换到不同的 B。 那你可以r[2] = new_value; return【参考方案2】:

@Dustin 这应该可以帮助您完成正在完成的挑战。

name_length = 16
b_length = 8
start = 0
record_count = 0
records = []

# KISS Method - 2nd Attempt - Read in 16, 16, 8 and output to file

for i in range(start, len(data)):
  record = data[start:start + name_length] 
  records.append(record[0:16])
  start += name_length

  record = data[start:start + name_length]
  records.append(record[0:16])
  start += name_length

  record = data[start:start + b_length]
  records.append(record[0:8])
  start += b_length

  record_count += 1

file1.close()

【讨论】:

【参考方案3】:

Dustin - 对于 2D 列表 - 您需要使用以下内容 - 我认为这可行。

# Loads the file at filepath 
# Returns a 2d array with the data
# 
def load2dArrayFromFile(filepath):
  file = open(filepath, 'r')
  data = file.read()
  lines = data.split("\n")
  for i in range(0, len(lines)):
    lines[i] = lines[i].split("|")

  return lines

# Searches the 2d array 'records' for firstname, lastname.
# Returns the index of the record or -1 if no record exists
# 
def findIndex(records, firstname, lastname):
  for i in range(0, len(records)):
    if (records[i][0] == firstname and records[i][1] == lastname):
      return [i]
    return -1

# Sets the birthday of the record at the given index
# Returns: nothing
def setBirthday(records, index, newBirthday):
  if (index >= 0):
    records[index][2] = newBirthday

# Convert the 2d array back into a string
# Return the text of the 2d array
def makeTextFrom2dArray(records):
  for i in range(0, len(records)):
    records[i] = "|".join(records)
  return ("\n".join(records))

# ----------------------------------------------------------------
# 
#  Our main code body, where we call our functions.
#  
# ----------------------------------------------------------------

# Load our records from the file into a 2d array
records= load2dArrayFromFile(P)

# Find out which index, if any, has the name we are hunting
indexWeAreHunting= findIndex(records, F, L)

# Set the birthday record to the one we were passed
setBirthday(records, indexWeAreHunting, B)

# Convert the records into a text string
output= makeTextFrom2dArray(records)

# write the text string out to the file

【讨论】:

诀窍是查看传入的数据文件 - 如果您查看源数据,您会一次看到一行带有“|”分隔符。因此,您首先必须按每个新行“\n”拆分,然后在“|”上拆分。这应该能让你继续前进,也许那里有一个小错误,但我相信它很干净。

以上是关于固定长度记录的主要内容,如果未能解决你的问题,请参考以下文章

用于固定长度文本文件的 .NET 库

查看固定长度数组之间有多少字节相等的最快方法

js生成随机固定长度字符串的简便方法

使用 scala spark 将固定宽度的文件插入 Hive

如何将一个数组拆分成多个固定长度的数组

Netty进阶——粘包与半包(固定长度方式解决粘包问题)