【问题标题】:AWK to Python For MboxAWK 到 Python For Mbox
【发布时间】:2019-08-20 21:31:32
【问题描述】:

在 python 中实现这个 awk 命令的最佳 Pythonic 方式是什么?

awk 'BEGIN{chunk=0} /^From /{msgs++;if(msgs==500){msgs=0;chunk++}}{print > "chunk_" chunk ".txt"}' mbox

我现在用它来分割大量邮箱(mbox 格式)文件。

我现在正在尝试递归方法。

def chunkUp(mbox, chunk=0):
    with open(mbox, 'r') as bigfile:
        msg = 0
        for line in bigfile:
            if msg == 0: 
                with open("./TestChunks/chunks/chunk_"+str(chunk)+".txt", "a+") as cf:
                    if line.startswith("From "): msg += 1
                    cf.write(line)
                    if msg > 20: chunkUp(mbox, chunk+1)

我希望能够在 python 中实现这一点,并且能够在它被中断时恢复进度。现在正在处理那一点。

我要把我的大脑打成结!干杯!

【问题讨论】:

  • 递归不好,因为文件没有关闭(一段时间后打开的文件太多)
  • 好点,我将放弃这种方法。

标签: python awk mbox


【解决方案1】:

您的递归方法注定要失败:您可能会同时打开太多文件,因为 with 块直到程序结束才会退出。

最好打开一个句柄并写入,在遇到“From”时关闭并重新打开新句柄。

也以写入模式打开您的文件,而不是追加。下面的代码尝试执行最少的操作和测试来将每一行写入文件,并在找到From: 时关闭/打开另一个文件。另外,最后,最后一个文件被关闭了。

def chunkUp(mbox):
    with open(mbox, 'r') as bigfile:
        handle = None
        chunk = 0

        for line in bigfile:
            if line.startswith("From "):
                 # next (or first) file
                 chunk += 1
                 if handle is not None:
                    handle.close()
                 handle = None

            # file was closed / first file: create a new one
            if handle is None:
               handle = open("./TestChunks/chunks/chunk_{}.txt".format(chunk), "w")
            # write the line in the current file
            handle.write(line)

         if handle is not None:
             handle.close()

我还没有测试过,但它很简单,它应该可以工作。如果文件的第一行没有“From”,则之前的所有行都存储在chunk_0.txt文件中。

【讨论】:

  • 我一直在尝试使用 open()。这是一个绝妙的解决方案。我将按照 awk 命令指定的每个块实现 500 msg。我将其标记为已回答,因为它处理了处理打开文件的心理障碍。谢谢!
猜你喜欢
  • 2018-11-15
  • 2012-10-11
  • 2020-12-29
  • 2020-10-01
  • 2018-02-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2017-11-26
相关资源
最近更新 更多