Sed and awk 笔记之 sed 篇:简单介绍

最近在阅读《sed & awk》,这本书是sed和awk相关书籍中比较经典的一本。我在读书的时候有一个习惯,就是会作一些笔记,如果有条件我会放到博客中。写博客不仅是给别人看的,更是写给自己看的,同时因为写给别人看,所以必然会在一些细节的地方写得很清楚明了,可以加深自己对原书的理解,同时以后回头看的时候,我自己也能快速的回忆起来。

另外一方面,我会选择英文原版来阅读而非中文翻译版,主要是出于英文版的内容更加准确、容易领会作者的本意这个方面的原因。毕竟翻译的内容一方面因为翻译的时候会丢失一些原版的意思,同时因为不同的人有不同的理解,在翻译中可能会夹杂着自己个人的理解。就好比这一系列的文章,许多内容都是出自原书,我只不过是翻译了些内容加了点注解而已,所心也只能称之为笔记。

文中对一些术语的翻译只是按本人自己的喜好而定,请见谅。

本系列包含两部分的内容:sed篇和awk篇。

sed篇总共分成6章:

Sed&awk笔记之sed篇:简单介绍

Sed&awk笔记之sed篇:模式空间与地址匹配

Sed&awk笔记之sed篇:sed基础命令

Sed&awk笔记之sed篇:高级命令(一)

Sed&awk笔记之sed篇:高级命令(二)

Sed&awk笔记之sed篇:实战

sed篇总共分成6章:(简书版)

Sed&awk笔记之sed篇:简单介绍

Sed&awk笔记之sed篇:模式空间与地址匹配

Sed&awk笔记之sed篇:sed基础命令

Sed&awk笔记之sed篇:高级命令(一)

Sed&awk笔记之sed篇:高级命令(二)

Sed&awk笔记之sed篇:实战

awk篇暂时还未计划。

Sed&awk笔记之awk篇:快速了解Awk(一)

Sed&awk笔记之awk篇:快速了解Awk(二)

Sed&awk笔记之awk篇:快速了解Awk(三)

Sed是什么

《sed and awk》一书中(1.2 A Stream Editor)是这样解释的:

Sed is a "non-interactive" stream-oriented editor. It is stream-oriented because, like many UNIX

programs, input flows through the program and is directed to standard output.

Sed本质上是一个编辑器,但是它是非交互式的,这点与VIM不同;同时它又是面向字符流的,输入的字符流经过Sed的处理后输出。这两个特性使得Sed成为命令行下面非常有用的一个处理工具。

如果对sed的历史有兴趣,可以看书中2.1节"Awk, by Sed and Grep, out of Ed",这里就不多介绍。

基本概念

sed命令的语法如下所示:

sed [options] script filename

同大多数Linux命令一样,sed也是从stdin中读取输入,并且将输出写到stdout,但是当filename被指定时,则会从指定的文件中获取输入,输出可以重定向到文件中,但是需要注意的是,该文件绝对不能与输入的文件相同。

options是指sed的命令行参数,这一块并不是重点,参数也不多。

script是指需要对输入执行的一个或者多个操作指令(instruction),sed会依次读取输入文件的每一行到缓存中并应用script中指定的操作指令,因此而带来的变化并不会影响最初的文件(注:如果使用sed时指定-i参数则会影响最初的文件)。如果操作指令很多,为了不影响可读性,可以将其写到文件中,并通过-f参数指定scriptfile:

sed -f scriptfile filename

这里有一个建议,在命令行中指定的操作指令最好用单引号引起来,这样可以避免shell对特殊字符的处理(如空格、$等,关于这一点可以参考简洁的Bash编程技巧续篇 - 9. 引号之间的区别)。这个建议同样适用grep/awk等命令,当然如果有时候确实不适合使用单引号时,记得对特殊字符转义。

无论是将操作指令通过命令行指定,还是写入到文件中作为一个sed脚本,必须包含至少一个指令,否则用sed就没有意义了。一般会同时指定多个操作指令,这时候指令之间的顺序就显得非常重要。而你的脑海中必须有这么一个概念,即每个指令应用后,当前输入的行会变成什么样子。要做到这一点首先必须要了解sed的工作原理,要做到“知其然,且知其所以然”。

每条操作指令由pattern和procedure两部分组成,pattern一般是用'/'分隔的正则表达式(在sed中也有可能是行号,具体参见Sed命令地址匹配问题总结),而procedure则是一连串编辑命令(action)。

sed的处理流程,简化后是这样的:

读入新的一行内容到缓存空间;

从指定的操作指令中取出第一条指令,判断是否匹配pattern;

如果不匹配,则忽略后续的编辑命令,回到第2步继续取出下一条指令;

如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;

当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;

当所有行都处理完之后,结束;

具体流程见下图:

简单例子

概念如果脱离实际的例子就会显得非常枯燥无趣,这本书在这一点上处理得很好,都是配上实际的例子来讲解的。不过有点遗憾的是,书中的例子大多是与troff macro有关的,我们很难有条件来实际测试例子,在笔记中我会尽量使用更加浅显易懂的例子来说明。

下面是摘自书中的一个例子,假设有个文件list:

John Daggett, 341 King Road, Plymouth MA

Alice Ford, 22 East Broadway, Richmond VA

Orville Thomas, 11345 Oak Bridge Road, Tulsa OK

Terry Kalkas, 402 Lans Road, Beaver Falls PA

Eric Adams, 20 Post Road, Sudbury MA

Hubert Sims, 328A Brook Road, Roanoke VA

Amy Wilde, 334 Bayshore Pkwy, Mountain View CA

Sal Carpenter, 73 6th Street, Boston MA

这个例子中用到的知识点都会在后文中介绍,你可以先知道有这个东西就行。

假如,现在打算将MA替换成Massachusetts,可以使用替换命令s:

$ sed-e's/MA/Massachusetts/'listJohnDaggett,341KingRoad,PlymouthMassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,SudburyMassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,BostonMassachusetts

这里面的-e选项是可选的,这个参数只是在命令行中同时指定多个操作指令时才需要用到,如:

$ sed-e's/ MA/, Massachusetts/'-e's/ PA/, Pennsylvania/'listJohnDaggett,341KingRoad,Plymouth,MassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFalls,PennsylvaniaEricAdams,20PostRoad,Sudbury,MassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,Boston,Massachusetts

即使在多个操作指令的情况下,-e参数也不是必需的,我一般不会加-e参数,比如上面的例子可以换成下面的写法:

$ sed's/ MA/, Massachusetts/;s/ PA/, Pennsylvania/'list

操作指令之间可以用分号分隔,这点和shell命令可以用分号分隔是一样的。

这里提前说一点使用s替换命令需要小心的地方,不要忘记结尾的斜杠,如果你遇到下面的错误说明你犯了这个错误:

$ sed-e's/ MA/, Massachusetts'list

sed:-e expression#1, char 21: unterminated `s' command

假如这时,我只想输出替换命令影响的行,而不想输出文件的所有内容,需要怎么办?这个时候可以利用替换命令s的p选项,它会将替换后的内容打印到标准输出。但是仅仅这样是不够的,否则输出的结果并非我们所想要的:

$ sed-e's/ MA/, Massachusetts/p'listJohnDaggett,341KingRoad,Plymouth,MassachusettsJohnDaggett,341KingRoad,Plymouth,MassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,Sudbury,MassachusettsEricAdams,20PostRoad,Sudbury,MassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,Boston,MassachusettsSalCarpenter,736thStreet,Boston,Massachusetts

从上面可以看出,文件的所有行都被打印到标准输出,并且被替换命令修改的行输出了两遍。造成这个问题的原因是,sed命令应用完所有指定之后默认会将当前行打印输出,所以就有了上面的结果。解决方法是在使用sed命令是指定-n参数,该参数会抑制sed默认的输出:

$ sed-n's/ MA/, Massachusetts/p'listJohnDaggett,341KingRoad,Plymouth,MassachusettsEricAdams,20PostRoad,Sudbury,MassachusettsSalCarpenter,736thStreet,Boston,Massachusetts

正则表达式

书中的第3章的内容都是介绍正则表达式,这是因为sed的很多地方都需要用到正则表达式,比如操作指令的pattern部分以及替换命令中用到的匹配部分。关于正则这部分可以看Linux/Unix工具与正则表达式的POSIX规范,文章中已经讲得非常清楚了,我自已在忘记一些内容的时候也是去查阅这篇文章。

由于篇幅限制,本篇就到此为止,下一篇见Sed&awk笔记之sed篇:模式空间与地址匹配

转自:团子的小窝, 本文固定链接:Sed and awk 笔记之 sed 篇:简单介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容