Python 根据字符串从 1 个文件创建 3 个文件

标签 python linux

我有一个大型数据集,存储在 Linux 上的一个文件中。我想编写一个 python 脚本,该脚本将获取此文件并根据 3 个特定字符串的第一次出现将其写入 3 个文件。

我的数据集如下所示:

Handle: A1
OrgID: AA
Name: Name1

Handle: A2
OrgID: BB 
Name: Name2

OrgID: 1111
OrgName: Name1
Street: 1111 Street

OrgID: 2222
OrgName: Name2
Street: 2222 Street

NetHandle: Net1
OrgID: AA
Parent: Net1

NetHandle: Net2
OrgID: BB
Parent: Net2

我希望第一个文件包含以“Handle”开头的所有条目,并在以“OrgID”开头的条目之前停止。第二个文件包含以“OrgID”开头的条目,第三个文件以“NetHandle”开头。棘手的部分是 OrigID 位于这三个文件中。我已经尝试了堆栈和其他站点上的示例中的几种方法,但尚未能完成此操作。任何帮助将不胜感激。

最佳答案

假设您发布的内容是文字文件格式,最简单的做法是一次读取 4 行的 block 并打开第一行。1

<小时/>

我们可以使用grouper recipe from the itertools docs ,它可以将任何东西分成任意固定大小的组。但我会向您展示如何在没有食谱的情况下做到这一点,因为值得了解它是如何工作的:

with open('dataset.txt', 'r') as f:
    # Create a list with 4 references to the same iterator.
    iters = [iter(f)] * 4
    # Zip into an iterator that grabs one value from each reference.
    chunks = zip(*iters)
    # Now each chunk is a tuple of four successive values.
    for chunk in chunks:
<小时/>

现在,我们如何打开组?这里要做的最简单的事情是创建一个将标签映射到输出文件的字典:

outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}

...然后从每个 block 中提取标签并查找输出文件:

firstline = chunk[0]
label = firstline.split(':')[0]
outfile = outfiles[label]

您可能需要在这里进行一些错误处理。但是,如果您非常确定该文件没有任何与这三种格式之一不完全匹配的 block ,那么这可能就足够了。2

<小时/>

放在一起:

with open('dataset.txt', 'r') as f, open('handles.txt', 'w') as handles, \
      open('orgs.txt', 'w') as orgs, open('nets.txt', 'w') as nets:
    outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}
    for chunk in zip(*([iter(f)]*4)):
        label = chunk[0].split(':')[0]
        outfiles[label].writelines(chunk)

或者,如果您使用石斑鱼食谱(您应该这样做):

with open('dataset.txt', 'r') as f, open('handles.txt', 'w') as handles, \
      open('orgs.txt', 'w') as orgs, open('nets.txt', 'w') as nets:
    outfiles = {'Handle': handles, 'OrgID': orgs, 'NetHandle': nets}
    for chunk in grouper(f, 4):
        label = chunk[0].split(':')[0]
        outfiles[label].writelines(chunk)
<小时/>

如果文件实际上并非以换行符结尾,则最后一个 block 将会失败。但是您可以通过将 '' 指定为 fillvalue 来轻松解决此问题:

    for chunk in grouper(f, 4, ''):
<小时/>

<子>1。如果您可以假设所有 Handle block 首先出现,然后是所有 OrgID block ,然后是所有 NetHandle block ,则可以使事情变得更高效(尽管不是那么简单)。但当我问这是否属实时,你只是回答“它们都是大块的”,这无助于解决歧义。因此,我将编写它来处理它们混合的可能性。

<子>2。如果您错了,并且其中一个 block 以 'Spam:' 开头,您将收到 KeyError: 'Spam'。或者,如果其中一个 block 的长度不是 4 行,那么您最终会不同步并读取 Street: 作为第一行,您将得到 KeyError: 'Street'。因此,任何意外的输入都应该很容易调试。

关于Python 根据字符串从 1 个文件创建 3 个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51029419/

相关文章:

python - 我怎样才能让我的模型接受 2 个张量作为输入。我尝试过使用合并层,但我没有完全让它工作

python - 打开 Azure StorageStreamDownloader 而不将其另存为文件

python - 我想运行像 make , make install 和 python setup install 这样的命令

linux - 如何在文件中每一行的开头均匀地添加一组值?

MySQL 服务器无法在 PowerPC 架构上启动

python - 将具有变量指数的 Sympy 表达式与零进行比较

python - 升级到 1.1.0 后 Matplotlib 停止工作

Python 输出歧义

python - 这是在Python中获取窗口大小的方法

linux - 公平、安全、高效、多语言的沙盒