从制表符分隔的文件中提取部分数据

时间:2012-08-23 19:49:35

标签: python bash parsing tab-delimited-text

我在维基百科编辑历史记录中有一个文本分隔文件。每行包含一个不同的维基百科编辑。该文件按页面标题排序,以便每个页面的每个编辑都是它自己的行(该行用制表符分隔7个不同的变量)。我需要的只是每页的第一次和最后一次编辑。我想要的是一个类似的文件,每个维基百科页面只有一行,每行包含该页面的第一次和最后一次编辑的所有信息。基本上是一行是文件中第一行和最后一行的组合。

我想知道是否有一个简单的bash脚本或短的python代码(我可以在mac osx终端中运行),它将通过txt文件并输出我想要的内容。

感谢您的帮助!

以下是该文件的前几行,以了解它的外观:

6   233188  AmericanSamoa   2001-01-19T01:12:51Z    ip:office.bomis.com ip:office.bomis.com 1516
6   133180191   AmericanSamoa   2007-05-24T14:41:33Z    Ngaiklin    4477979 5
8   233189  AppliedEthics   2001-01-20T15:01:12Z    ip:pD950754B.dip.t-dialin.net   ip:pD950754B.dip.t-dialin.net   9
8   133180238   AppliedEthics   2007-05-24T14:41:48Z    Ngaiklin    4477979 6
10  233192  AccessibleComputing 2001-01-21T02:12:21Z    RoseParks   99  8
10  133180268   AccessibleComputing 2007-05-24T14:41:58Z    Ngaiklin    4477979 6
12  18201   Anarchism   2002-02-25T15:00:22Z    ip:Conversion_script    ip:Conversion_script    1214
12  19746   Anarchism   2002-02-25T15:43:11Z    ip:140.232.153.45   ip:140.232.153.45   1460
12  19749   Anarchism   2002-02-27T17:34:09Z    ip:24.188.31.147    ip:24.188.31.147    1474

给出上述行的输出示例如下所示:(请记住,每个页面的编辑数量从2到数百不等,我只需要对每个页面进行第一次和最后一次编辑。我会类似于以下示例的输出,其中每个页面都有一行包含第一个和最后一个编辑信息。

6   233188  AmericanSamoa   2001-01-19T01:12:51Z    ip:office.bomis.com ip:office.bomis.com 1516    2007-05-24T14:41:33Z    Ngaiklin    4477979 5
8   233189  AppliedEthics   2001-01-20T15:01:12Z    ip:pD950754B.dip.t-dialin.net   ip:pD950754B.dip.t-dialin.net   9    2007-05-24T14:41:48Z   Ngaiklin    4477979 6
10  233192  AccessibleComputing 2001-01-21T02:12:21Z    RoseParks   99  8   2007-05-24T14:41:58Z    Ngaiklin    4477979 6
12  18201   Anarchism   2002-02-25T15:00:22Z    ip:Conversion_script    ip:Conversion_script    1214   2002-02-27T17:34:09Z ip:24.188.31.147    ip:24.188.31.147    1474

2 个答案:

答案 0 :(得分:1)

您的示例输出有点不一致,因为第一行的文章名称是两次。假设您并不真的需要它,并且假设文件已正确排序,则以下命令对您的示例起作用:

sed -r ':r;$!{N;br};s/\n/#/g;s/(^|#)((\S+\s+){2})(\S+\s+)([^#]*).*#(\S+\s+){2}\4/\1\2\4\5/g;s/#/\n/g' history.txt

另一个假设是您的文件不包含任何#个字符,否则您需要将#更改为文件中未遇到的其他内容。

我猜你需要一些解释,但首先我要确保它能满足您的需求。请评论结果:)

P.S。它会立即处理整个文件,对你来说可能太慢了。

答案 1 :(得分:0)

我会分两步完成。

  • 假设您的数据已被组织为字符串列表(例如,使用file.readlines()),列表为data。我们开始构建一个字典,将第一列作为键,其值为2个列表的列表,第一个是第一个条目,第二个是最后一个条目。

    results = {}
    for line in data.split("\n"):
        fields = line.strip().split("\t")
        tag = fields[0]
        if tag:
            tag = int(tag)
            if tag in results:
                # last entry: skip the first three fields
                results[tag][1] = fields[3:]
            else:
                # first entry: skip the first field
                results[tag] = [fields[1:], []]
    
  • 现在我们有了字典,只需要对它进行排序,将两个列表组合在一起并打印结果

    ordered_results = []
    for k in sorted(results.keys()):
        current = results[k]
        ordered_results.append(current[0]+current[1])
    print "\n".join("\t".join(row) for row in ordered_results)