1.   版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址
  2.  
  3.   http://www.cnblogs.com/Colin-Cai/p/7663831.html
  4.  
  5.   作者:窗户
  6.  
  7.   QQ6679072
  8.  
  9.   E-mail6679072@qq.com

  sed是所谓的流编辑器,我们经常用它来做一些文本替换的事情,这是sed最擅长的事情,如sed 's/Bob/Tom/g'就是把文章中所有的Bob改成Tom。

  sed是图灵完备的,作为sed的粉丝,喜欢用sed做各种sed不擅长的事情,这里实现一下wc -w的功能,也就是统计文章单词数量。

  我习惯喜欢加上n和r,n表示每行结束时不会自动打印,r表示正则表达式的扩展方式,我实在很讨厌写那么多\,所以sed基本上我是一定加这两个东西的。

  先从sed擅长的开始,先用s命令做替换,把每个单词都替换为单个1。这一步其实很简单,s/[^ \t\r]+/1/g即可,也就是把不是空格的连续匹配替换为1,g是表示对一行中所有满足这样的模式都替换为1,再考虑到正则表达式的贪婪,其实我们的[^ \t\r]+实际上就是指完整的一个单词,熟悉regex替换的应该不难理解。

  然后为了整齐,替换为1之后,再把空格都去掉,其实也就是把不是1的去掉,那么紧接着一条s/[^1]+//g即可,然后再用p打印一下。

  一口吃不成胖子,先从简单的来,我们可以看一下效果。在此之前先找篇文章,就节选一下google的pixel buds新闻吧。

  1. linux-p94b:/tmp/testhere # cat 1.txt
  2. American company Google recently announced the release of its Google Pixel 2 phone and other products that work together with the phone.
  3. One of the new products is a pair of wireless earphones Google calls Pixel Buds.
  4. The earphones are seen as the company's answer to competitor Apple's popular AirPod headphones.
  5. At a launch event on October 4, Google said its Pixel Buds were built to provide high-quality sound and hands-free use. All of their operations can be controlled by simply touching the right earphone.
  6. Once the headphones are paired with a Pixel phone, its many features can be used through the Pixel Buds.
  7. One example is Google Assistant, the company's artificial intelligence, or AI, service. Users can now talk directly to Pixel Buds to ask Google Assistant questions, get information or other help. This can all be done without touching the telephone.
  8. The Pixel Buds also can work with Google Translate, the service that provides words and expressions in over 100 languages.
  9. Google product manager Juston Payne demonstrated this feature during the launch event. He was able to talk with someone whose native language is Swedish.
  10. When the person spoke Swedish into the Pixel Buds, the phone's speakers provided the translation in English. The English speaker's response was then translated in real time into Swedish and heard through the Pixel Buds.
  11. linux-p94b:/tmp/testhere # cat wc-w.sed
  12. #!/usr/bin/sed -nrf
  13. s/[^ \t\r]+/1/g
  14. s/[^1]+//g
  15. p
  16. linux-p94b:/tmp/testhere # ./wc-w.sed <1.txt
  17. 1111111111111111111111
  18. 111111111111111
  19. 11111111111111
  20. 1111111111111111111111111111111111
  21. 1111111111111111111
  22. 111111111111111111111111111111111111111
  23. 11111111111111111111
  24. 111111111111111111111111
  25. 11111111111111111111111111111111111

  对一下,确实没有错,只是出来了一堆1,而且还是分行的,那么第二步,把这个分行给去掉。当然,加个管道,tr -d '\n'就去掉了,不过我们要的是单个sed解决,那么需要再动一点点脑筋。

  我们可以在上面的基础上稍微改动改动,把这些1先缓存进保持空间(hold space),最后再从保持空间中取出,然后用s/\n//g去掉所有的回车符,再打印。

  1. linux-p94b:/tmp/testhere # cat wc-w.sed
  2. #!/usr/bin/sed -nrf
  3. s/[^ \t\r]+/1/g
  4. s/[^1]+//g
  5. H
  6. $ {
  7. g
  8. s/\n//g
  9. p
  10. }
  11. linux-p94b:/tmp/testhere # ./wc-w.sed <1.txt
  12. 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

  H命令就是放在保持空间的最后,$是判定输入结束,g是用保持空间的内容替换模式空间。

  上面打印出了222个1,离结果222已经很近了。

  最后就是如何整合成222了,这里的确是需要一点点技巧了。我们建立以下计数方法:

  1..1;1..1;1..1...

每一堆1的个数假设为nk,nk-1,...,n0

  允许数量为0的堆

  每一堆1之间用分号隔开,如果看到有多个分号在一起,那么中间实际上有数量为0的堆

  整个计数表示的是nk*10k+nk-1*10k-1+...+n0

  很明显,我们十进制表示方法和整个很类似,只是,十进制表示里,每一堆都小于10而已。

  于是我们可以创立一个算法,也就是,当我们发现一堆里有10个1,那么我们就可以往高位进1。

  很容易证明这个算法可以结束。

  假设{nk,nk-1,...,n0}有限序列是非负整数num的一个表示,序列里的每一个数字是一个非负整数,最高位nk大于0,除非num等于0。

  显然,一个具体整数的表示方法是有限的,实际上,这个k不可能大于num对10取对数,序列中的每一项不可能大于num。

  序列可以比较大小,

  {mj,mj-1,...,m0}有限序列是num的另外一个表示,那么

  {nk,nk-1,...,n0} 〉{mj,mj-1,...,m0} 当且仅当 k > j  或者    k = j且nk=mk...nk-p=mk-p,nk-p-1>mk-p-1

  以上比较大小的方法可以把一个非负整数的所有表示串成一个全序集。

  之前的算法中,每当升位,其表示都会变的比之前大。因为所有的表示为有限个,而最大的表示则是十进制的表示方法,从而可以知道算法是可以结束得到十进制表示的。

  那么我们根据这个,不停的找10个0,每当找到,就进位,最后再把每堆挨个替换为9,8,7,6,5,4,3,2,0,再去掉分号,就完成了。有点费脑子吧,我实现一下如下:

  1. linux-p94b:/tmp/testhere # cat wc-w.sed
  2. #!/usr/bin/sed -nrf
  3. s/[^ \t\r]+/1/g
  4. s/[^1]+//g
  5. H
  6. $ {
  7. g
  8. s/\n//g
  9. :a
  10. s/;1111111111/1;/
  11. s/^1111111111/1;/
  12. ta
  13. s/111111111/9/g
  14. s/11111111/8/g
  15. s/1111111/7/g
  16. s/111111/6/g
  17. s/11111/5/g
  18. s/1111/4/g
  19. s/111/3/g
  20. s/11/2/g
  21. :b
  22. s/;;/;0;/g
  23. tb
  24. s/;$/;0/
  25. s/;//g
  26. /^$/s/^/0/
  27. p
  28. }
  29. linux-p94b:/tmp/testhere # ./wc-w.sed <1.txt
  30. 222

  

  

用sed实现wc -c的功能的更多相关文章

  1. 用sed实现wc -w的功能

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7663831.html 作者:窗户 Q ...

  2. 模仿WC.exe的功能实现--node.js

    Github项目地址:https://github.com/102derLinmenmin/myWc WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要 ...

  3. WC的基本功能实现.(Java)

    我的GitHub地址:https://github.com/Yuetao1219/lessons WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写 ...

  4. 软件工程:java实现wc项目基本功能

    项目相关要求 项目地址:https://github.com/xiawork/wcwork 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处理多个 ...

  5. 软件工程:Java实现WC.exe基本功能

    项目相关要求 GitHub地址:https://github.com/3216004716/WC 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处 ...

  6. sed - 文本三剑客之编辑功能

    sed - stream editor for filtering and transforming text Sed是一个流编辑器.流编辑器用于对输入流(文件或管道输入)执行基本的文本转换.虽然在某 ...

  7. 文本处理命令--wc、sed

    一.wc wc命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 测试文件内容: (my_python_env)[root@hadoop26 ~]# cat test hnlinu ...

  8. 用c语言基本实现wc.exe功能

    网址:https://github.com/3216005214/wc.exe wc项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿 ...

  9. 软件工程—WC功能实现 (JAVA)

    软件工程-WC功能实现(JAVA) Github项目地址:https://github.com/Ousyoung/wc 项目要求 ​ wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和 ...

随机推荐

  1. Python3 多线程的两种实现方式

    最近学习 Python3 ,希望能掌握多线程的使用,在此做个笔记.同时也希望Python 牛人指点错误.关于线程的概念,前面简单总结了一下 java 的多线程,传送门:java 多线程概念,三种创建多 ...

  2. 201521123042 《java程序设计》 第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. ①泛型定义:泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展, ...

  3. 201521123079《java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过? ...

  4. java课程设计团队博客

    java课程设计 本组主题:Calculator(简易计算器) 功能要求:基本实现计算器的功能,可运行加.减.乘.除.求倒数.求平方根.求百分号运算.正负数运算等 一.团队介绍 团队名称:熬夜做不出随 ...

  5. MarkDown 例子

    一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...

  6. Day-14: 常用的内建模块

    collections包含对tuple.list.dict等派生出新功能 namedtuple用来为tuple类型派生出一个新名字的tuple类,并提供用属性引出的功能. >>> f ...

  7. UVW源码漫谈(二)

    前一篇发布出来之后,我看着阅读量还是挺多的,就是评论和给意见的一个都没有,或许各位看官就跟我一样,看帖子从不回复,只管看就行了.毕竟大家都有公务在身,没太多时间,可以理解.不过没关系,我是不是可以直接 ...

  8. sscanf和正则表达式

    sscanf() - 从一个字符串中读进与指定格式相符的数据.      函数原型: Int sscanf( string str, string fmt, mixed var1, mixed var ...

  9. svn服务器配置与客户端的使用

    1, Apache Subversion 官网下载地址: http://subversion.apache.org/packages.html#windows 官网下载提供的一般都是最新版本的,如果想 ...

  10. mysql 安装-zip版

    1.千万不要自己新建data,使用命令:mysqld --initialize会自动生成一大堆文件 2.没有ini文件就自己新建: