2012-08-23 102 views
0

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

我想知道是否有一个简单的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 
+1

欢迎StackOverflow上的问题。请对您的标签进行更多选择。这个问题与维基百科本身无关。这是关于解析制表符分隔的文本。 :-)如果你指出你在询问什么操作系统和编程/脚本语言,它也会有所帮助;如果有人提供了bash脚本并且您正在运行Windows,或者如果您使用的是OS X,那么它将不会很好。您可以编辑您的问题以添加适当的标签。如果您在问题和标签中提供详细信息,它可以帮助您更快地获得答案。 :-) –

+1

请包括一些示例输出。很难说出这里要问什么。 – Steve

+0

如果您可以确保文件正确排序,即。通过标题和日期,您可以编写一个PHP/Perl/Python脚本,其中包含读取,保存标题和输出标题更改代码。我认为这比在bash中做事容易得多。如果你的文件没有被排序,你可以使用散列图实现相同的功能。去一趟,发布一些代码进行审查,而不是让人们为你写这个东西。 – Pete855217

回答

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.它一次处理整个文件,可能对你来说太慢了。

+0

这真是令人印象深刻的一点sed正则表达式那里列弗!在我的* nix框上运行良好,但是当我在Mac上运行它时会重复每行,并为整个正则表达式提供“未使用的标签”消息。即使我将-r标志(* nix)更改为-E以在Mac上为sed获取扩展正则表达式,也会发生这种情况。 – Pete855217

+0

@Pete感谢您的反馈!我在修改POSIX命令时遇到了一些麻烦,任何帮助都是值得赞赏的。 –

+0

@Pete这个可以在Mac上使用吗? 'sed':r; $!{N; br}; s/\ n /#/ g; s/\(^ \ |#\)\(\([[:alnum:]] \ {1,\} [[:空白:]] \ {1,\} \)\ {2 \} \)\([[:alnum:]] \ {1,\} [[:空白:]] \ {1,\} \)\([^#] * \)*#\([[:alnum:]] \ {1,\} [[:空白:]] \ {1,\} \)\ {2 \} \ 4/\ 1 \ 2 \ 4 \ 5/g; s /#/ \ n/g'history.txt' –

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) 
    
相关问题