[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创] 跟我一起学文本处理:gsed/gawk快速入门[20130416更新]

本帖最后由 namejm 于 2013-4-16 20:53 编辑

前言

  自从淡出论坛之后,namejm一直在批处理的文本处理方面无所进展,转而求诸perl、ruby、AutoHotKey之流,零敲碎打,一事无成。
  忽有一日,zm900612传给我一份关于sed处理文本的流程的介绍资料,阅后顿觉丹田发热,任督二脉中气流乱窜,四肢百骸无比舒坦,一时间耳聪目明,以往向我紧闭的gsed/gawk大门轰然洞开, 从此步入用gsed/gawk处理文本的坦途。
  以往在仅仅使用纯批处理代码的时候,处理单个文件尚觉得心应手,但是,文件一旦多起来,或者体积急剧增大之后,要处理的情况就更复杂了,不使用命令行工具来增强批处理代码,往往会束手无措。自从用上了gsed/gawk之后,海量数据的处理也游刃有余。每每看到论坛里很多人还在无比艰辛地用纯批处理来操作文本,总觉无比心酸——要是换成gsed/gawk来做,该是多么轻松的一件事情啊!于是萌发了写一个关于gsed/gawk快速入门教程的想法,把我对gsed/gawk的理解与大家分享。
  这个教程,我不会弄成一个事无巨细的帮助手册,只挑选那些我认为会经常用到的功能来重点介绍,既有内功心法,也有具体招式,着眼于让大家迅速入门,可能会有一些图片来增强讲解效果。由于本人尚未精通gsed/gawk,不可能高屋建瓴做全面的讲解,也没有做系统的讲解规划,下面的介绍也只是我的入门理解,可能还存在着这样或那样的错误,希望发现了问题的xdjm能予以指正,谢谢。
  但愿它不要再像N年前的那个for教程那样,拖拖拉拉更新了两年多,最后虎头蛇尾弄成了个烂尾工程,吊人胃口不说,还有误人子弟之嫌。

  教程的初步大纲如下

一、 我为什么需要gsed/gawk
二、 gsed/gawk很难学吗
三、 如何获取gsed/gawk
四、 使用gsed/gawk的3种方式
五、 gsed/gawk的处理过程
六、 gsed/gawk下的正则表达式
七、 gsed的简要讲解
八、 gawk的简要讲解
九、 常见代码讲解
十、 其他
3

评分人数

    • lky216: 文采极好技术 + 1
    • plp626: 期待大作PB + 10
    • cjiabing: 谢谢辛苦工作好分享!~PB + 12 技术 + 1
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

20130228更新

本帖最后由 namejm 于 2013-4-16 21:01 编辑

一、我为什么需要gsed/gawk

  Windows下使用批处理,我做得最多的是处理文本文件:抽取含有某些字符串的行、以某些字符为分隔符提取特征行的第N列、替换字符串A为字符串B……写过“中英文互译”、“公交线路查询”、“身份证信息查询”等小工具,甚至配合命令行版的下载工具整理过数百本在线小说、抓过论坛的上千万张图片,还玩出了查重补漏、断点续传之类的花样,据说还有牛人用批处理写过论坛灌水机,连图片验证都照过不误。古希腊伟大的物理学家阿基米德曾说过:给我一个支点,我就能撬起整个地球!面对批处理,我甚至一度产生过这样的错觉:没有做不到,只有想不到,给我一个好的idea,我就能用批处理做出来!

  但是,这仅仅是我的错觉而已。实际上,用批处理写代码是非常辛苦的:没有专门的调试器,调试代码只能手工一遍又一遍不厌其烦地添加/删除echo和pause语句、在黑乎乎的cmd窗口中观察代码的运行结果;大数或浮点数计算,还得自行设计算法、甚至模拟手工算式进行按位计算;字符串操作,仅提供了几个简陋的查找、替换功能,更复杂的操作,只能for了再for,call了再call,即使你折腾得昏天黑地,也不见得就能实现你的目标……

  具体到文本处理这一块,在windows下自带的批处理脚本中,用于处理文本的语句/工具虽然较多,但存在着这样或那样的限制:替换字符串中的字符,可以用set语句,但是你不能选择替换指定的位置,并且待替换的字符串不能超过8186字符(精确的数据尚未全面验证,但不会超过8192,下同);搜索指定字符串,findstr虽然能限定字符串是出现在行首还是行尾,但你无法限定它们的重复次数;一些复杂的操作,比如对一篇文本先抽取含有指定内容的行,再删除一些特定字符,用for语句虽然大致能办到,但你不得不考虑每行的字符数是否超过8186字符的限制、有没有包含百分号感叹号等特殊字符、如何才能只针对某行的某个特定部位进行操,如果文件巨大的话,你还得考虑处理速度是否足够快……

  总而言之,windows下的很多文字处理语句/工具,虽然能实现某些操作,但是这些功能的实现是需要付出沉重代价的:要么操作部位无法做到精准、要么字符串不能超长、要么会丢失一些特殊字符、要么处理效率异常低下难以忍受。如果不借助外部工具,在windows下用批处理对文本进行操作,即使你绞尽脑汁使出浑身解数,甚至仍然无法实现某些功能。

  即使在批处理的世界里摸爬滚打了6、7年,在接触到gsed和gawk之前,每当需要用批处理来处理一大堆文本时,我都如履薄冰,我常扪心自问:这些文本有超长字符串的行存在吗?包含特殊字符吗?替换时能做到精准匹配吗?如果是海量数据,处理速度够快吗……每当这些问题萦绕于心时,我总会有一种心虚气短头皮发麻的感觉。

  自从找到了gsed和gawk之后,我这些烦恼就一扫而空了。

  与windows下自带的文本处理语句/工具相比,gsed和gawk具备如下一些特点,足以使得它们在文本处理领域中傲视群雄:

1、支持正则表达式

  支持正则表达式,是gsed/gawk最突出的特点。可以说,gsed/gawk之所以能成为命令行下的文字处理利器,在Liunx下是无可替代的工具,很大程度上是因为有了对正则表达式的支持。如果没有了对正则表达式的支持,gsed/gawk就会失去灵魂,被抽掉了脊梁,彻底沦为可有可无的玩具,也就没有了扬名立万的资本。

  正则表达式是一种充满魔力的技术,它是用一组简单的符号代码来描述文本的组成规律,常被用来做字符串的匹配工作:查找纯英文字母的行、搜索某个字符串重复指定次数的行、寻找第N位出现某个字符串的行……这些操作对正则表达式来说是小菜一碟。如果正则表达式同时被应用于搜索和替换中,那么,从一大堆杂乱无章的文本中抽取自己想要的内容,并且以一种便于阅读的排版格式展现出来,将不再是一种奢求。君不见,EditPlus、UltraEdit、EmEditor、gVim之流,纷纷加入了对正则表达式的支持;至于那些以格式化文本为主要功能的TexPro、cnBook、排版助手之类的软件,更是以正则表达式作为其主要功能的基础和支柱。反观那些以文字处理为主,但又不支持正则表达式的软件,比如系统自带的记事本,通过搜索来定位时,查找某个指定的字符串还凑合,但是像查找像“以script打头的行”、“纯英文字母的行”之类的内容时,它们就无能为力了。不经历磨难的人生,是不完整的人生;不支持正则表达式的文本处理工具,不是一个完整的文本处理工具。而某款文本处理工具一旦支持了正则表达式,它就会达到一个更高的境界,绝对会在众多的同类软件中脱颖而出,想不红都很困难。

2、支持超长字符串

  批处理对字符串的长度是有很大限制的:set语句设置变量时,字符串长度不能超过8186个;在用findstr搜索一些超大文本时,比如每行有上百M字符的文本,会报“字符串超长”之类的错误。虽然一般情形下,我们要处理的文本,每行的字符串比较短,可能就只有几十百来字的规模,但是,碰到一些比较变态的网页文件,每行上千字符是常有的事,甚至一个上M的网页文件,可能整个文件就只有一行,如果把这些上M的字符串赋予某个变量,批处理脚本绝对会挂掉;如果碰上更变态的,比如那些服务器的日志文件,几百M甚至上G,就别指望set或findstr能干活了。

  而gsed/gawk,它们可没那么多的限制,再大的文件也咽得下,它们唯一的限制就是——你的内存究竟有多大?换句话说,如果你的内存有2G,并且打算把它们全部用于gsed或gawk,那么,gsed/gawk将不会辜负你的希望,它们真的就能每次处理2G的行!如果某个文件有10G,总共有10行字符串,那么,2G的内存下用gsed或gawk来处理绰绰有余。

3、处理速度超快

  假如有一个10M的文本文件需要进行一些比较复杂的搜索和替换操作,经过最佳优化的纯批处理代码,其处理的耗时可能是几分钟甚至几个小时,而换成gsed/gawk,很可能就是几秒到10来秒的时间!甚至几百M上G的文本,gsed/gawk都有可在数分钟内处理完毕,两者的差距是极其巨大的——没办法,谁叫gsed/gawk是专门用于处理海量文本数据的呢?如果处理速度不能接近或达到C,反倒要落后于一般的通用脚本语言,你叫gsed/gawk情何以堪?



二、gsed/gawk很难学吗

  sed和awk原本是Linux系统下以文本处理见长的命令行工具,sed的原意是文本流编辑器(Stream EDitor),awk得名于它们最初的三个发明者姓名的首字母的组合(Alfred V. Aho、Peter J. We i n b e rg e r和Brian W. Kernighan),后被GNU组织移植到了Windows下,故名gsed和gawk。

  在很多人的映像中,gsed/gawk的代码虽然简洁,但晦涩难懂,有如天书,从而本能地产生一种畏惧排斥心理。

  其实,gsed/gawk代码一点也不神秘,只需要捅破几层窗户纸,一切都会豁然开朗。

  这几层窗户纸分别是:正则表达式、gsed以行为单位处理文本、gsed的两大内存空间和gawk把文本视为数据库记录的格式进行处理的方式,而贯穿始终的,则是正则表达式

  于是,学习的难点就转到正则表达式上来了。

  正则表达式仅有有限的几组元字符,通过对这些元字符的排列组合,可以写出无穷的表达式,用来描述五花八门的文本组合。可以说,正则表达式极其简洁,但是非常灵活,拥有强大的字符串描述功能,其功能之强大,超乎想象。

  要学好gsed/gawk的正则表达式,仅需要掌握为数不多的几组元字符的用法,并在头脑中具备“贪婪模式”和“惰性模式”之类的观念就行了。

  想当初,本人仅凭借从网上收集的为数不多的一点零碎的正则表达式知识,在理解了gsed的两大内存空间的运作原理之后,短短数天就掌握了gsed的用法,写出了几段像模像样的代码,进而掌握了gawk,从此一发不可收拾,用gsed/gawk干起了在线整理文本小说、论坛抓图、批量下载mp3、整理输入法码表、整理英语词库之类的勾当,线上线下忙得不亦乐乎,现在更是热情高涨,准备把我的一些粗浅的心得整理出来,幻想着有朝一日能著书立说,三尺讲台上,也能人模狗样地传经布道一回……无限YY中^_^——本人一介文科生,被IT行业甩开了N条大街,所学非所用,gsed/gawk尚能玩得像模像样,何况诸君乎?
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

20130416更新

本帖最后由 namejm 于 2013-4-16 20:58 编辑

三、如何获取gsed/gawk

  Gsed的官方网站为:http://www.gnu.org/software/sed/
  Gawk的官方网站为:http://www.gnu.org/software/gawk/
  但是,在官方网站中,你基本上不可能找到可供Windows使用的exe格式文件。要想获得exe格式的文件,可以从下面两个网站寻找。
  1.        http://gnuwin32.sourceforge.net/packages.html
  2.        http://code.google.com/p/gnu-on-windows/downloads/list
  第1个网站中的版本有些旧,但是除了gsed/gawk之外,还有很多其他有用的命令行工具可供把玩;第2个网站提供的基本上是最新的版本。

四、使用gsed/gawk的3种方式

  你可以通过以下3种方式使用gsed/gawk。

  1.在cmd命令行窗口中使用命令。

  例如:打印出文件 test.txt 中含有字符串 bathome 的所有行,gsed命令可以写为:
  1. gsed –n “/bathome/p” test.txt
复制代码
gawk 命令可以写为:
  1. gawk “/bathome/{print $0}” test.txt
复制代码
把命令写在命令行窗口中的好处,是可以方便调试单行命令。

  2.把gsed/gawk命令写在批处理文件中。

  把命令写在批处理文件中的写法和在cmd窗口中的写法是一样的,只是写在批处理文件中,可以一次性写入多条命令,可以很方便地测试多条命令的执行结果。

  3.把gsed/gawk命令写在单独的脚本文件中。

  以上两种方法都有比较大的局限性:这些命令都只能写在同一行上,无法分成多行书写,当某条gsed/gawk命令很长,或者其中有条件判断或流程跳转时,挤在同一行上将十分难以阅读,甚至有些复杂语句根本就不能出现在同一行上。
  这个时候,就需要把gsed/gawk语句放在一个单独的脚本文件中,比如把语句保存在 test.sed/test.awk中,后缀名可以任意取,甚至不要后缀名,但是需要保存为文本格式,然后在批处理文件中通过
  1. gsed –f test.sed test.txt>result.txt
复制代码
  1. gawk –f test.awk test.txt>result.txt
复制代码
之类的语句,把对 test.txt 的处理结果放到 result.txt 中。-f test.sed 表明在批处理文件中,通过gsed调用脚本文件 test.sed 来处理test.txt 。-f 取自ScriptFile,指明紧跟其后的是一个外部的脚本文件。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

占楼备用。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

返回列表