文本处理的小诀窍

Posted 无敌大壮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本处理的小诀窍相关的知识,希望对你有一定的参考价值。

文本处理的小诀窍

场景描述

  • 原始文本格式:

        pid1 kid1
        pid3 kid1
        pid1 kid2
        pid1 kid3
        pid2 kid3
        pid2 kid4
  • 需要统计的结果:每条pid可以跟哪几个kid关联,最终结果格式:

        pid1 kid1,kid2,kid3
        pid2 kid3,kid4
        pid3 kid1

* 原始文本大概有2亿多行

处理思路

  • 将文本按第一列排序,排序后效果:
    pid1 kid1
    pid1 kid2
    pid1 kid3
    pid2 kid3
    pid2 kid4
    pid3 kid3
  • 将第一列相同的行合并,效果:
    pid1 kid1,kid2,kid3
    pid2 kid3,kid4
    pid3 kid1
    

具体解决代码

    # sort -k 1 -n src.txt > sort1.txt
    # cat sort1.txt | php -B \'
          $pidtmp = 0;
          $kidtmp = array();
      \' -R \'
          list($pid, $kid) = explode("\\t", $argn);
          if($pid != $pidtmp) {
              echo "\\n".$pidtmp."\\t".implode(",", array_keys($kidtmp));
              $pidtmp = $pid;
              $kidtmp = array();
          }
          $kidtmp[$kid] = 1;
      \'

以上两条命令可实现需求,共耗时半个小时左右

其它说明

本需求中存在一个原始文档,这个文档是通过其它程序生成的。那么存在一个疑问,为什么其它程序生成文档时,不直接生成所需要的格式(即以上示例的最终格式),而是生成一个中间格式的文档。

 

其实在设计之前的程序时,确实就是期望直接输出以上的最终文档,但出现一个问题就是这个最终文档要怎么存储,存mysql还是nosql。尝试过mysql,一共有2亿行结果,每一行就需要读、写一次mysql,时间成本太高。然后也尝试了redis,使用列表存储,每一行原数据,只需要写一次redis的列表,可以减少一次读,然而时间还是太长,所以才将中间结果输入到文本。再使用以上提到的2条命令将结果转换为最终格式,时间成本大降低。

 

如果有另外一个程序需要根据pid来搜索以上生成的最终文档,可以借鉴另一篇文章 ,入口

以上是关于文本处理的小诀窍的主要内容,如果未能解决你的问题,请参考以下文章

20+ css高频实用片段,提高幸福感的小技能你可以拥有噢

使用case语句的3个诀窍

Sublime Text编辑器的12个技巧和诀窍

12个不可不知的Sublime Text应用技巧和诀窍

一个文本处理的小练习:

微信小程序代码片段