Sed简明教程

awk于1977年出生,今年36岁本命年,sed比awk大2-3岁,awk就像林妹妹,sed就是宝玉哥哥了。所以  林妹妹跳了个Topless,他的哥哥sed坐不住了,也一定要出来抖一抖。

sed全名叫stream editor,流编辑器,用程序的方式来编辑文本,相当的hacker啊。sed基本上就是玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。

同样,本篇文章不会说sed的全部东西,你可以参看sed的手册,我这里主要还是想和大家竞争一下那些从手机指缝间或马桶里流走的时间,用这些时间来学习一些东西。当然,接下来的还是要靠大家自己双手。

用s命令替换

我使用下面的这段文本做演示:


1

2

3

4

5

6

7

8

9


$catpets.txt

This is mycat

  mycat's name is betty

This is my dog

  my dog's name is frank

This is my fish

  my fish's name is george

This is my goat

  my goat's name is adam

把其中的my字符串替换成Hao Chen’s,下面的语句应该很好理解(s表示替换命令,/my/表示匹配my,/Hao Chen’s/表示把匹配替换成Hao Chen’s,/g 表示一行上的替换所有的匹配):


1

2

3

4

5

6

7

8

9


$sed"s/my/Hao Chen's/g"pets.txt

This is Hao Chen'scat

  Hao Chen's cat's name is betty

This is Hao Chen's dog

  Hao Chen's dog's name is frank

This is Hao Chen's fish

  Hao Chen's fish's name is george

This is Hao Chen's goat

  Hao Chen's goat's name is adam

注意:如果你要使用单引号,那么你没办法通过\’这样来转义,就有双引号就可以了,在双引号内可以用\”来转义。

再注意:上面的sed并没有对文件的内容改变,只是把处理过后的内容输出,如果你要写回文件,你可以使用重定向,如:

1 $sed"s/my/Hao Chen's/g"pets.txt > hao_pets.txt

或使用 -i 参数直接修改文件内容:

1 $sed-i"s/my/Hao Chen's/g"pets.txt

在每一行最前面加点东西:


1

2

3

4

5

6

7

8

9


$sed's/^/#/g'pets.txt

#This is my cat

#  my cat's name is betty

#This is my dog

#  my dog's name is frank

#This is my fish

#  my fish's name is george

#This is my goat

#  my goat's name is adam

在每一行最后面加点东西:


1

2

3

4

5

6

7

8

9


$sed's/$/ --- /g'pets.txt

This is mycat---

  mycat's name is betty ---

This is my dog ---

  my dog's name is frank ---

This is my fish ---

  my fish's name is george ---

This is my goat ---

  my goat's name is adam ---

顺手介绍一下正则表达式的一些最基本的东西:

  • ^ 表示一行的开头。如:/^#/ 以#开头的匹配。
  • $ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
  • \< 表示词首。 如 \<abc 表示以 abc 为首的詞。
  • \> 表示词尾。 如 abc\> 表示以 abc 結尾的詞。
  • . 表示任何单个字符。
  • * 表示某个字符出现了0次或多次。
  • [ ] 字符集合。 如:[abc]表示匹配a或b或c,还有[a-zA-Z]表示匹配所有的26个字符。如果其中有^表示反,如[^a]表示非a的字符

正规则表达式是一些很牛的事,比如我们要去掉某html中的tags:

html.txt

1 <b>This</b> is what <spanstyle="text-decoration: underline;">I</span> meant. Understand?

看看我们的sed命令


1

2

3

4

5

6

7

8


# 如果你这样搞的话,就会有问题

$sed's/<.*>//g'html.txt

 Understand?

 

# 要解决上面的那个问题,就得像下面这样。

# 其中的'[^>]' 指定了除了>的字符重复0次或多次。

$sed's/<[^>]*>//g'html.txt

This is what I meant. Understand?

我们再来看看指定需要替换的内容:


1

2

3

4

5

6

7

8

9


$sed"3s/my/your/g"pets.txt

This is mycat

  mycat's name is betty

This is your dog

  my dog's name is frank

This is my fish

  my fish's name is george

This is my goat

  my goat's name is adam

下面的命令只替换第3到第6行的文本。


1

2

3

4

5

6

7

8

9


$sed"3,6s/my/your/g"pets.txt

This is mycat

  mycat's name is betty

This is your dog

  your dog's name is frank

This is your fish

  your fish's name is george

This is my goat

  my goat's name is adam

 


1

2

3

4

5


$catmy.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

只替换每一行的第一个s:


1

2

3

4

5


$sed's/s/S/1'my.txt

ThiS is mycat, mycat's name is betty

ThiS is my dog, my dog's name is frank

ThiS is my fish, my fish's name is george

ThiS is my goat, my goat's name is adam

只替换每一行的第二个s:


1

2

3

4

5


$sed's/s/S/2'my.txt

This iS mycat, mycat's name is betty

This iS my dog, my dog's name is frank

This iS my fish, my fish's name is george

This iS my goat, my goat's name is adam

只替换第一行的第3个以后的s:


1

2

3

4

5


$sed's/s/S/3g'my.txt

This is mycat, mycat'S name iS betty

This is my dog, my dog'S name iS frank

This is my fiSh, my fiSh'S name iS george

This is my goat, my goat'S name iS adam

多个匹配

如果我们需要一次替换多个模式,可参看下面的示例:(第一个模式把第一行到第三行的my替换成your,第二个则把第3行以后的This替换成了That)


1

2

3

4

5


$sed'1,3s/my/your/g; 3,$s/This/That/g'my.txt

This is yourcat, yourcat's name is betty

This is your dog, your dog's name is frank

That is your fish, your fish's name is george

That is my goat, my goat's name is adam

上面的命令等价于:(注:下面使用的是sed的-e命令行参数)

1 sed-e'1,3s/my/your/g'-e'3,$s/This/That/g'my.txt

我们可以使用&来当做被匹配的变量,然后可以在基本左右加点东西。如下所示:


1

2

3

4

5


$sed's/my/[&]/g'my.txt

This is [my]cat, [my]cat's name is betty

This is [my] dog, [my] dog's name is frank

This is [my] fish, [my] fish's name is george

This is [my] goat, [my] goat's name is adam

圆括号匹配

使用圆括号匹配的示例:(圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,sed中使用的是\1,\2…)


1

2

3

4

5


$sed's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g'my.txt

cat:betty

dog:frank

fish:george

goat:adam

上面这个例子中的正则表达式有点复杂,解开如下(去掉转义字符):

正则为:This is my ([^,]*),.*is (.*)
匹配为:This is my (cat),……….is (betty)

然后:\1就是cat,\2就是betty

sed的命令

让我们回到最一开始的例子pets.txt,让我们来看几个命令:

N命令

先来看N命令 —— 把下一行的内容纳入当成缓冲区做匹配。

下面的的示例会把原文本中的偶数行纳入奇数行匹配,而s只匹配并替换一次,所以,就成了下面的结果:


1

2

3

4

5

6

7

8

9


$sed'N;s/my/your/'pets.txt

This is yourcat

  mycat's name is betty

This is your dog

  my dog's name is frank

This is your fish

  my fish's name is george

This is your goat

  my goat's name is adam

也就是说,原来的文件成了:


1

2

3

4


This is mycat\n  mycat's name is betty

This is my dog\n  my dog's name is frank

This is my fish\n  my fish's name is george

This is my goat\n  my goat's name is adam

这样一来,下面的例子你就明白了,


1

2

3

4

5


$sed'N;s/\n/,/'pets.txt

This is mycat,  mycat's name is betty

This is my dog,  my dog's name is frank

This is my fish,  my fish's name is george

This is my goat,  my goat's name is adam

a命令和i命令

a命令就是append, i命令就是insert,它们是用来添加行的。如:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


# 其中的1i表明,其要在第1行前插入一行(insert)

$sed"1 i This is my monkey, my monkey's name is wukong"my.txt

This is my monkey, my monkey's name is wukong

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

 

# 其中的1a表明,其要在最后一行后追加一行(append)

$sed"$ a This is my monkey, my monkey's name is wukong"my.txt

This is mycat, mycat's name is betty

This is my monkey, my monkey's name is wukong

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

我们可以运用匹配来添加文本:


1

2

3

4

5

6

7


# 注意其中的/fish/a,这意思是匹配到/fish/后就追加一行

$sed"/fish/a This is my monkey, my monkey's name is wukong"my.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

This is my monkey, my monkey's name is wukong

This is my goat, my goat's name is adam

下面这个例子是对每一行都挺插入:


1

2

3

4

5

6

7

8

9


$sed"/my/a ----"my.txt

This is mycat, mycat's name is betty

----

This is my dog, my dog's name is frank

----

This is my fish, my fish's name is george

----

This is my goat, my goat's name is adam

----

c命令

c 命令是替换匹配行


1

2

3

4

5

6

7

8

9

10

11


$sed"2 c This is my monkey, my monkey's name is wukong"my.txt

This is mycat, mycat's name is betty

This is my monkey, my monkey's name is wukong

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

 

$sed"/fish/c This is my monkey, my monkey's name is wukong"my.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my monkey, my monkey's name is wukong

This is my goat, my goat's name is adam

d命令

删除匹配行


1

2

3

4

5

6

7

8

9

10

11

12


$sed'/fish/d'my.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my goat, my goat's name is adam

 

$sed'2d'my.txt

This is mycat, mycat's name is betty

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

 

$sed'2,$d'my.txt

This is mycat, mycat's name is betty

p命令

打印命令

你可以把这个命令当成grep式的命令


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23


# 匹配fish并输出,可以看到fish的那一行被打了两遍,

# 这是因为sed处理时会把处理的信息输出

$sed'/fish/p'my.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

This is my fish, my fish's name is george

This is my goat, my goat's name is adam

 

# 使用n参数就好了

$sed-n'/fish/p'my.txt

This is my fish, my fish's name is george

 

# 从一个模式到另一个模式

$sed-n'/dog/,/fish/p'my.txt

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

 

#从第一行打印到匹配fish成功的那一行

$sed-n'1,/fish/p'my.txt

This is mycat, mycat's name is betty

This is my dog, my dog's name is frank

This is my fish, my fish's name is george

几个知识点

好了,下面我们要介绍四个sed的基本知识点:

Pattern Space

第零个是关于-n参数的,大家也许没看懂,没关系,我们来看一下sed处理文本的伪代码,并了解一下Pattern Space的概念:


1

2

3

4

5

6

7

8

9

10

11

12


foreach line in file {

    //放入把行Pattern_Space

    Pattern_Space <= line;

 

    // 对每个pattern space执行sed命令

    Pattern_Space <= EXEC(sed_cmd, Pattern_Space);

 

    // 如果没有指定 -n 则输出处理后的Pattern_Space

    if(sed option hasn't"-n")  {

       print Pattern_Space

    }

}

Address

第一个是关于address,几乎上述所有的命令都是这样的(注:其中的!表示匹配成功后是否执行命令)

[address[,address]][!]{cmd}

address可以是一个数字,也可以是一个模式,你可以通过逗号要分隔两个address 表示两个address的区间,参执行命令cmd,伪代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14


boolbexec =false

foreach line in file {

    if( match(address1) ){

        bexec =true;

    }

 

    if( bexec ==true) {

        EXEC(sed_cmd);

    }

 

    if( match (address2) ) {

        bexec =false;

    }

}

关于address可以使用相对位置,如:


1

2

3

4

5

6

7

8

9

10


# 其中的+3表示后面连续3行

$sed'/dog/,+3s/^/# /g'pets.txt

This is mycat

  mycat's name is betty

# This is my dog

#   my dog's name is frank

# This is my fish

#   my fish's name is george

This is my goat

  my goat's name is adam

命令打包

第二个是cmd可以是多个,它们可以用分号分开,可以用大括号括起来作为嵌套命令。下面是几个例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35


$catpets.txt

This is mycat

  mycat's name is betty

This is my dog

  my dog's name is frank

This is my fish

  my fish's name is george

This is my goat

  my goat's name is adam

 

# 对3行到第6行,执行命令/This/d

$sed'3,6 {/This/d}'pets.txt

This is mycat

  mycat's name is betty

  my dog's name is frank

  my fish's name is george

This is my goat

  my goat's name is adam

 

# 对3行到第6行,匹配/This/成功后,再匹配/fish/,成功后执行d命令

$sed'3,6 {/This/{/fish/d}}'pets.txt

This is mycat

  mycat's name is betty

This is my dog

  my dog's name is frank

  my fish's name is george

This is my goat

  my goat's name is adam

 

# 从第一行到最后一行,如果匹配到This,则删除之;如果前面有空格,则去除空格

$sed'1,${/This/d;s/^ *//g}'pets.txt

mycat's name is betty

my dog's name is frank

my fish's name is george

my goat's name is adam

Hold Space

第三个我们再来看一下 Hold Space

接下来,我们需要了解一下Hold Space的概念,我们先来看四个命令:

g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容

这些命令有什么用?我们来看两个示例吧,用到的示例文件是:


1

2

3

4


$catt.txt

one

two

three

第一个示例:


1

2

3

4

5

6

7

8

9


$sed'H;g't.txt

one

 

one

two

 

one

two

three

是不是有点没看懂,我作个图你就看懂了。

第二个示例,反序了一个文件的行:


1

2

3

4


$sed'1!G;h;$!d't.txt

three

two

one

其中的 ’1!G;h;$!d’ 可拆解为三个命令

  • 1!G —— 只有第一行不执行G命令,将hold space中的内容append回到pattern space
  • h —— 第一行都执行h命令,将pattern space中的内容拷贝到hold space中
  • $!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行

这个执行序列很难理解,做个图如下大家就明白了:

就先说这么多吧,希望对大家有用。

http://sed.sourceforge.net/sed1line_zh-CN.html

时间: 2024-10-02 18:57:35

Sed简明教程的相关文章

【转】sed 简明教程

本文转自:http://coolshell.cn/articles/9104.html awk于1977年出生,今年36岁本命年,sed比awk大2-3岁,awk就像林妹妹,sed就是宝玉哥哥了.所以 林妹妹跳了个Topless,他的哥哥sed坐不住了,也一定要出来抖一抖. sed全名叫stream editor,流编辑器,用程序的方式来编辑文本,相当的hacker啊.sed基本上就是玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强. 同样,本篇文章不会说sed的全部东西,你可以参看s

perl 简明教程 perl教程集合_perl

参考:http://shouce.jb51.net/perl5/ 网站环境配置:http://www.jb51.net/article/74005.htm Perl的基本语法 http://www.jb51.net/shouce/Perl.htm 前言:perl是什么,干什么用的?perl原来设计者的意图是用来处理 字符的,80%的强项是处理字符,当然其它的很多都可以.现在很多网页也是用perl的,通常需要CGI环境,比如 $char =~ /语言/ ,意思是查找含有"语言"这两个字的

F#简明教程二:F#类型系统和类型推断机制

在上一篇教程<F#与函数式编程概述>中我们了解到F#和函数式编程的一些特点,更多关于F#语言和函数式编程的介绍可以参考51CTO之前对微软MVP赵颉老师的专访<TechED 09视频专访:F#与函数式编程语言>.本节教程我们将学习到F#的一些基础原理,在开始之前,让我们先温习一下我们的Hello World代码: #light System.Console.WriteLine("This is one hello") printfn "This is

XML简明教程目录

XML简明教程第1课: 处理XML元素 XML简明教程第2课: 处理XML文档 XML简明教程第3课 处理XML数据岛 XML简明教程第4课: 使用XML对象模型 XML简明教程第5课:使用XML名域 XML简明教程第6课 使用XML Schema XML简明教程第7课:在XML文档中使用数据类型 XML简明教程第8课:访问经过类型定义的XML值 XML简明教程第9课:使用C++ XML DSO XML简明教程第10课 :C++ XML DSO中使用主/细节特征 XML简易教程之一 XML简易教

XSL简明教程目录

XSL简明教程(1)XSL入门 XSL简明教程(2)XSL转换 XSL简明教程(3)在客户端的实现 XSL简明教程(4)在服务器端的实现 XSL简明教程(5)XSL的索引 XSL简明教程(6)XSL过滤和查询 了解WEB页面工具语言XML(一)背景 了解WEB页面工具语言XML(二)定义 了解WEB页面工具语言XML(三)支持工具 了解WEB页面工具语言XML(四)应用分类 了解WEB页面工具语言XML(五)好处 了解WEB页面工具语言XML(六)展望

Linux防火墙iptables简明教程

  前几天微魔部落再次遭受到个别别有用心的攻击者的攻击,顺便给自己充个电,复习了一下linux下常见的防火墙iptables的一些内容,但是无奈网上的很多教程都较为繁琐,本着简明化学习的目的,微魔为大家剔除了许多冗余的内容,提取出尽量多的精华部分成文,和大家共同学习,本文涉及的内容包括如下 Linux防火墙iptables简明教程 1.安装iptables 2.查看现有的iptables规则 3.删除某iptables规则 4.清除现有iptables规则 5.创建规则 6.设置开机启动 7.保

Python类的定义、继承及类对象使用方法简明教程

  这篇文章主要介绍了Python类的定义.继承及类对象使用方法简明教程,本文用浅显易懂的语言讲解了类的定义.继承及类对象的使用,非常实用易懂,需要的朋友可以参考下 Python编程中类的概念可以比作是某种类型集合的描述,如"人类"可以被看作一个类,然后用人类这个类定义出每个具体的人--你.我.他等作为其对象.类还拥有属性和功能,属性即类本身的一些特性,如人类有名字.身高和体重等属性,而具体值则会根据每个人的不同;功能则是类所能实现的行为,如人类拥有吃饭.走路和睡觉等功能.具体的形式如

Jquery插件编写简明教程

 这篇文章主要介绍了Jquery插件编写简明教程,jquery插件开发实例,需要的朋友可以参考下  代码如下: /*  1.jQuery插件文件名推荐命名为 jquery.[插件名].js 以免和其他javascript库插件混淆.例如命名为jquery.color.js  2.所有的对象方法名都应当附加到jQuery.fn对象上而所有的全局函数都应当附加到jQuery对象本身上.  3.在插件内部,this指向的是当前通过选择器获取的jquery对象,而不像一般方法哪样,例如chick()方法

Java 8简明教程

原文地址 本文由 ImportNew - 黄小非 翻译自 winterbe.欢迎加入翻译小组.转载请见文末要求. ImportNew注:有兴趣第一时间学习Java 8的Java开发者,欢迎围观<征集参与Java 8原创系列文章作者>. 以下是<Java 8简明教程>的正文. "Java并没有没落,人们很快就会发现这一点" 欢迎阅读我编写的Java 8介绍.本教程将带领你一步一步地认识这门语言的新特性.通过简单明了的代码示例,你将会学习到如何使用默认接口方法,La