【问题标题】:How to merge few lines with filtering some text如何通过过滤某些文本合并几行
【发布时间】:2018-11-25 19:09:31
【问题描述】:

我有一个格式如下的文本文件。

第一行包含“USERID”=12345678,其他行包含每个应用程序的用户组: 例如:

用户 T 号为 T12345 的用户拥有对 APP1 和 APP2 的写入权限以及对 APP1 的只读权限。

T-Number 只是其他类型的 ID。

00001、00002等是序号,可以忽略。

T12345;;USERID;00001;12345678;
T12345;APPLICATION;WRITE;00001;APP1
T12345;APPLICATION;WRITE;00002;APP2
T12345;APPLICATION;READ-ONLY;00001;APP1

我需要做一些过滤并将包含 USERID 的行与所有具有用户组的行合并,将 t-number 与 userid (T12345 = 12345678) 匹配

所以输出应该是这样的。

12345678;APPLICATION;WRITE;APP1
12345678;APPLICATION;WRITE;APP2
12345678;APPLICATION;READ-ONLY;APP1

我应该使用 csv python 模块来完成这个吗?

【问题讨论】:

  • 您的文件格式不清楚。什么是“用户 T 号”?是另一种身份吗? 0000100002这两个数字有什么意义?
  • t-number 只是其他类型的 ID。 00001 和 00002 只是每种类型用户组的一些序号(00003、00004 等)
  • 那么这些数字在解析文件时可以忽略不计,还是在解析中有一定意义? (我注意到USERID 12345678 使用了两个不同的数字。
  • 它们可以忽略,如果我不够清楚,请道歉
  • 使用 csv 模块似乎是个好主意。

标签: python python-2.7 parsing merge


【解决方案1】:

我不太确定您是否应该在这里使用csv 模块 - 它包含混合数据,可能不仅仅是用户和用户组权限?在用户声明的情况下,您只需要检索其组和ID,而对于应用程序权限,您需要提取组、应用程序名称和权限。您拥有的不同数据越多,遇到的问题就越多 - 手动解析数据时,当您满足某些条件时,您总是可以continue

到目前为止,我必须说你最好手动逐行解析行,将其构造成有意义的东西,然后输出数据。比如

from StringIO import StringIO
from pprint import pprint

feed = """T12345;;USERID;00001;12345678;
T12345;;USERID;00001;2345678;
T12345;;USERID;00002;345678;
T12345;;USERID;00002;45678;
T12345;APPLICATION;WRITE;00001;APP1
T12345;APPLICATION;WRITE;00002;APP2
T12345;APPLICATION;READ-ONLY;00001;APP1
T12345;APPLICATION;WRITE;00002;APP1
T12345;APPLICATION;WRITE;00002;APP2"""

buf = StringIO(feed)

groups = {}

# Read all data into a dict of dicts
for line in buf:
  values = line.strip().split(";")
  if values[3] not in groups:
    groups[values[3]] = {"users": [], "apps": {}}
  if values[2] == "USERID":
    groups[values[3]]['users'].append(values[4])
    continue
  if values[1] == "APPLICATION":
    if values[4] not in groups[values[3]]["apps"]:
      groups[values[3]]["apps"][values[4]] = []
    groups[values[3]]["apps"][values[4]].append(values[2])

print("Structured data with group as root")
pprint(groups)

print("Output data")
for group_id, group in groups.iteritems():
  # Order by user, app
  for user in group["users"]:
    for app_name, rights in group["apps"].iteritems():
      for right in rights:
        print(";".join([user, "APPLICATION", right, app_name]))

Online demo here

【讨论】:

  • 非常感谢!看来我真的会进行手动解析,因为在我的特定需求中应用 csv 模块并没有多大用处
【解决方案2】:

我看不出使用csv 模块读取和解析输入文本文件有什么好处。字段的数量各不相同:USERID 行中有 6 个字段,其中 2 个为空,但其他行中有 5 个非空字段。这些字段看起来很简单,因此不需要csv 处理隐藏在引号等中的分隔符。没有 csv 文件中的标题行,而是在数据行之间散布了许多标题。

一个简单的例程读取每一行,在分号字符上分割每一行,解析该行,并组合相关的行就足够了。

输出文件是另一回事。这些行具有相同的格式,具有相同数量的字段。因此,创建该输出可能是 csv 的一个很好的用途。不过格式很简单,不用csv也可以创建文件。

【讨论】:

    猜你喜欢
    • 2022-11-13
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 2017-09-20
    • 2016-07-26
    相关资源
    最近更新 更多