http://www.web008.net

sed学习笔记

前言

环境:centos6.5

sed版本:GNU sed version 4.2.1

正文的代码都以在此个情状下验证的。

一、简介

sed(Stream Editor)意为流编辑器,是Unix不认为奇的一声令下路程序。是Bell实验室的 LeeE.McMahon 在一九七四年到1975年之间开荒完成,如今可以在好多操作系统中应用。

sed的面世是用作grep的二个传人,因为grep只好轻巧的举行寻找和替换,可是思量还也许会有删除等各类需求,McMahon 开垦了贰个更具通用性的工具。sed著名的语法则则饱含采纳 / 进行方式相配,以至 s/// 来举行代替。与同一时间存在的工具ed一同,sed的语法影响了新生向上的 ECMAScript 和 Perl。GNU sed 增加了数天性,富含有名的 in-place editing。

 

二、管理流程

要验证sed的管理流程,需求先提它的一声令下语法:

sed [options] script filename

诚如的话,sed是从stdin读取输入,并且将出口写出到stdout,但是filename被钦定期,会从钦赐的文本中收获输入,输出可以重定向到此外的公文中。

options指的是sed的命令行参数,比较有限,这些前边会表明。

script是指供给对输入实践的一个仍旧四个操作指令,貌似须要用单引号括起来,那样能够制止shell对特殊字符的拍卖。sed会依次读取输入文件的每黄金年代行到缓存中并使用script中钦赐的操作指令,因而而带给的转移并不会耳濡目染最早的文本(除非option加了-i参数)。

要是操作指令很多,为了不影响可读性,可以将其写入文件,并用-f参数钦命该公文:

sed -f scriptfile filename

随便将操作指令通过命令行内定,依然写入到文件中作为贰个sed脚本,必需包涵起码叁个限令,不然用sed就不曾意思了。

每条操作指令由patternprocedure两有个别组成,循名责实,pattern是同盟的规规矩矩,平日为用'/'分隔的正则表达式(也可能有超大希望是行号,具体参见Sed命令地址相配难题总括),而procedure则是数不尽编辑命令(action卡塔尔国。 sed的拍卖流程,简化后是那般的:

  1. 读入新的生龙活虎行内容到缓存空间;
  2. 从钦命的操作指令中收取第一条指令,推断是或不是相称pattern;
  3. 生机勃勃旦不相配,则忽影后续的编纂命令,回到第2步继续抽出下一条指令;
  4. 即便同盟,则指向缓存的行实行后续的编辑命令;落成后,回到第2步继续抽取下一条指令;
  5. 当有着指令都接收之后,输出缓存行的内容;回到第1步继续读入下大器晚成行内容;
  6. 当有着行都管理完之后,结束;

切实流程如图所示:

美高梅163888 1

 

三、命令选项options

基于上面提到的,大家领略sed常有两种语法情势:

sed [options] script filename
sed -f scriptfile filename

 

options常用的独有多少个:

-n :使用安静(silent卡塔尔(英语:State of Qatar)情势。在相仿 sed 的用法中,全数来自 STDIN 的数目貌似都会被列出到终端上。但万小米上 -n 参数后,则独有经过sed 特殊管理的那生龙活虎行(或许动作卡塔尔国才会被列出来。

-e :直接在命令列情势上张开 sed 的动作编排;

-f :直接将 sed 的动作写在多少个文书内, -f filename 则能够运转 filename 内的 sed 动作;

-r :sed 的动作扶持的是延伸型正规表示法的语法。(暗中同意是底子职业表示匈牙利(Magyarország卡塔尔国语法卡塔尔国

-i :直接订正读取的文书内容,实际不是出口到顶点。

 

在此边,-e参数实际上超级多时候会令人很吸引。因为我们平时接受sed的时候日常都不会加-e参数,举例:

seq 6 | sed -n '1,2p'

它和下边的写法是等价的:

seq 6 | sed -ne '1,2p'

据此重重稿子在说起-e那些参数的时候说可以大约,实际上,这种说法是不步步为营的。sed发展到今后,已经有二种各类的版本,在微微版本中,-e参数是不得以概括的,可是我们日常选用的都以GNU sed(gsed),所以在这里种景观能够简简单单。-e参数最常用的情景是对相通文件作数次校勘,如:

seq 6 | sed -e 's/1/10/' -e 's/2/20/'

只是实际上多种编排还也会有更简洁的写法,正是在同二个script中,用分号分割两句施命发号:

seq 6 | sed -e 's/1/10/;s/2/20/'

 

在处理流程部分,我们提到,每条操作指令script通常由patternprocedure两片段组成,接下来讲说pattern和procedure。

 

四、pattern

1. 情势空间

追忆一下方面讲到的处理流程,我们得以清楚,sed是以行的点子来拍卖数量的,每风姿洒脱行被读入到一块缓存空间,该空间名叫方式空间(pattern space卡塔尔(英语:State of Qatar)。因而sed操作的都以最先行的正片,同不时间继续的编辑命令都以应用到眼前的指令编辑后输出的结果,所以编辑命令之间的相继就显得非常首要。

让大家来看叁个特别轻便的例证,将风姿罗曼蒂克段文本中的pig替换到cow,况且将cow替换到horse:

echo "pig and cow and horse" | sed 's/pig/cow/;s/cow/hores/'

初看起来好像向来不难题,不过实际是大谬不然的,最后输出实际上是:

hores and cow and horse

案由是率先个替换命令将具备的pig都替换到cow,紧接着的替换命令是依据前二个结果管理的,将具备的cow都替换来horse,产生的结果是100%的pig/cow都被替换到了horse,那样违反了我们的初志。在这种景况下,只须要调换下多少个编辑命令的顺序:

echo "pig and cow and horse" | sed 's/cow/hores/;s/pig/cow/'

 

2. 形式空间的转变

sed只会缓存生龙活虎行的内容在情势空间,那样的功利是sed能够管理大文件而不会有任何难点,不像有些编辑器因为要三次性载入文件的一大块内容到缓存中而导致内部存款和储蓄器不足。

比方,今后要把生龙活虎段文本中的Unix System与UNIX System都要统意气风发替换来The UNIX Operating System,因而大家用两句替换命令来完结那几个指标:

echo "the Unix System" | sed 's/Unix/UNIX/;s/UNIX System/UNIX Operating System/'
==> the UNIX Operating System

进程轻巧的话如下:

1)读入大器晚成行内容到格局空间

2)应用第一条替换命令将Unix换来UNIX

3)形式空间的原委变为”the UNIX System”

美高梅163888,4)应用第二条替换命令将UNIX System替换到UNIX Operating System

5)情势空间的源委变为”the UNIX Operating System”

6)全数编辑命令实行完结,输出情势空间中的行

 

3. 地点相配

地址相称限定sed的编纂命令到底应用在怎么样行上。默许情形下,sed是大局相称的,即对具有输入行都应用钦点的编制命令,那是因为sed依次读入每豆蔻年华行,每风姿洒脱行都会化为近来进并被拍卖,所以s/apple/Pear/g会将富有输入行的apple替换来pear。

但即使由此点名地点范围,则只会更动范围内的行,比方:

echo "Harry loves apple" | sed '/Mary/s/apple/pear/'
==> Harry loves apple

/Mary/是一个正则表明式,表示格外满含Mary的行,因而”Harry loves apple”不会被替换.

sed命令中能够包涵0个、1个或者2个地址(地址对)。地址可认为正则表明式(如/Mary/),行号或者特别规的行符号(如$表示最后黄金时代行):

  • 如若未有一点名地址,私下认可将编写制定命令应用到持有行
  • 即使钦命三个地址,只将编写制定命令应用到相当该地点的行;
  • 后生可畏旦内定三个地点对(addr1,addr2卡塔尔(英语:State of Qatar),则将编辑命令应用到地方对中的全部行(包含初步和了结);
  • 假诺地方前面有二个感叹号(!),则将编写制定命令应用到不相称该地方的享有行

为了便于精晓上述剧情,大家以删除命令(d)为例来申明。

1)以行号内定地址

暗中同意不点名地址将会去除全部行:

sed 'd' file

钦赐地址则删除相称的行,如剔除第黄金时代行:

sed '1d' file

要么去除最终大器晚成行,$符号在这间表示最后生机勃勃行,这一点要下正则表明式中的含义不相同开来:

sed '$d' file

通过点名地址对能够去除该限量内的富有行,比方删除第3行到最终生机勃勃行:

sed '2,$d' file

那边经过点名行号删除,行号是sed命令内部维护的多少个计数变量,该变量独有贰个,并且在几个文件输入的情事下也不会被重新初始化。

 

2)通过正则表明式来钦赐地址

删去包括MA的行:

sed '/MA/d' file

去除从包蕴Alice的行开端到含有休伯特的行终止的全数行:

sed '/Alice/,/Hubert/d' file

自然,行号和地址对是能够混用的,删除第二行到含有Hubert的行终止的全部行:

sed '2,/Hubert/d' file

借使在地方前边钦赐感叹号(!),则会将下令应用到不般配该地方的行:

sed '2,/Hubert/!d' file

以上介绍的都以最中央之处相称格局,GNU Sed基于此增加了多少个扩展的款型,具体能够看man手册,或然能够看Sed 命令地址相称难点总计。

地方说的剧情都是对神工鬼斧的地址试行单个命令,若是要实施多个编辑命令要怎么办?sed中能够用{}来构成命令,就好比编制程序语言中的语句块,举个例子:

sed -n '1,4{s/ MA/, Massachusetts/;s/ PA/, Pennsylvania/;p}' file

 

五、procedure

对此sed编辑命令的语法有二种约定,分别是

[address]procedure               # 第一种
[line-address]procedure          # 第二种

第一种[address]是指可以为随便地址富含地点对,第三种[line-address]是指只可以为单个地址。

以下是要介绍的全套功底命令:

名称

命令

语法

说明

替换

s

[address]s/pattern/replacement/flags

替换匹配的内容

删除

d

[address]d

删除匹配的行

插入

i

[line-address]itext

在匹配行的前方插入文本

追加

a

[line-address]atext

在匹配行的后方插入文本

行替换

c

[address]ctext

将匹配的行替换成文本text

打印行

p

[address]p

打印在模式空间中的行

打印行号

=

[address]=

打印当前行行号

打印行

l

[address]l

打印在模式空间中的行,同时显示控制字符

转换字符

y

[address]y/SET1/SET2/

将SET1中出现的字符替换成SET2中对应位置的字符

读取下一行

n

[address]n

将下一行的内容读取到模式空间

读文件

r

[line-address]r file

将指定的文件读取到匹配行之后

写文件

w

[address]w file

将匹配地址的所有行输出到指定的文件中

退出

q

[line-address]q

读取到匹配的行之后即退出

 

1. 替换命令: s

语法:

[address]s/pattern/replacement/flags

其中[address]是指地址,pattern是替换命令的相称表明式,replacement则是呼应的更换内容,flags是指替换的标识位,它能够分包以下多少个依然四个值:

  • n: 一个数字(取值范围1-512),申明仅替换前n个被pattern相称的内容;
  • g: 表示全局替换,替换全部被pattern相称的剧情;
  • p: 仅当行被pattern匹配时,打字与印刷形式空间的剧情;
  • w file:仅当行被pattern相称时,将情势空间的开始和结果输出到文件file中;

 

倘若flags为空,则默许替换第一遍相配,如

echo "column1 column2 column3 column4" | sed 's/ /;/'
==> column1;column2 column3 column4

假诺flags中包蕴g,则意味着全局相称:

echo "column1 column2 column3 column4" | sed 's/ /;/g'
==> column1;column2;column3;column4

假若flags中明确钦定替换第n次的相配,比如n=2:

echo "column1 column2 column3 column4" | sed 's/ /;/2'
==> column1 column2;column3 column4

当替换命令的pattern与地方部分是如出意气风发辙的时候,比方/regexp/s/regexp/replacement/能够轻便替换命令中的pattern部分,那在单个编辑命令的情事下没多大用途,可是在整合命令的情景下也许能省不少素养的。

 

比如咱们有一个文本prince,里面包车型地铁内容是:

If someone loves a flower, of which just one single blossom grows in all the 

millions and millions of stars, it is enough to make him happy just to look at 

the stars. He can say to himself, "Somewhere, my flower is there…" But if the 

sheep eats the flower, in one moment all his stars will be darkened… And you think that is not important

!

至今要在flower前面扩张(“s”卡塔尔(قطر‎,同期在被退换的行前边增添+号,以下是使用的sed命令:

sed '/flower/{s//&("s")/;s/^/+ /}' prince

此地大家用到了组合命令,而且地址相称的一些和率先个替换命令的十总局分是一模二样的,所早前者我们大致了,在replacement部分选取了&其一元字符,它代表在此之前相称的开始和结果,那点大家在前边介绍。实践后的结果为:

+

 If someone loves a flower

("s"),

 of which just one single blossom grows in all the

millions and millions of stars, it is enough to make him happy just to look at 

+

 the stars. He can say to himself, "Somewhere, my flower

("s")

 is there…" But if the 

+

 sheep eats the flower

("s")

, in one moment all his stars will be darkened… And you think that is not important!

替换命令的一个技巧是中间的分隔符是可以更改的,这个技巧在有些地方非常有用,比如路径替换,下面是采用默认的分隔符和使用感叹号作为分隔符的对比:

find /usr/local -maxdepth 2 -type d | sed 's//usr/local/man//usr/share/man/'
find /usr/local -maxdepth 2 -type d | sed 's!/usr/local/man!/usr/share/man!'

 

轮换命令中还大概有二个很首要的局地——replacement(替换内容),将要相配的一些替换到replacement。在replacemnt部分中也可能有多少个特其他元字符,它们分别是:

  • &: 被pattern相配的剧情;
  • num: 被pattern相称的第num个分组(正则表达式中的概念,(..卡塔尔括起来的有些可以称作分组;
  • : 转义符号,用来转义&,, 回车等标记

2. 剔除命令: d

语法:

[address]d

除去命令能够用于删除多行内容,比方1,3d会删除1到3行。删除命令会将情势空间中的内容全方位删减,何况招致持续命令不会进行何况读入新行,因为眼前格局空间的开始和结果已经为空。大家能够尝试:

sed '2,${d;=}' prince 
==> If someone loves a flower, of which just one single blossom grows in all the

以上命令尝试在剔除第2行到终极风流倜傥行之后,打印当前进号(=卡塔尔国,不过实际并未执行该命令。

 

3. 插入行/追加行/替换行命令: i/a/c

语法:

# Append 追加
[line-address]atext
# Insert 插入
[line-address]itext
# Change 行替换 
[address]ctext

以上四个指令,行替换命令(c卡塔尔国允许地方为四个地方,其他多少个都只同意单个地址(注:在ArchLinux上测验表明,追加和插入命令都同意三个地点,sed版本为GNU sed version 4.2.1

扩大命令是指在协作的行后边插入文本text;相反地,插入命令是指相称的行前边插入文本text;最后,行替换命令会将同盟的行替换来文本text。文本text并从未被增加到情势空间,而是平素出口到显示器,由从此以后续的命令也不会接受到丰盛的文本上。注意,即便接收-n参数也不可能遏制增进的文本的输出。

作者们用实际的例子来大致介绍下那八个指令的用法,用地点的文件prince:

当今,大家要在第2行后边加多'------':

sed '2a
-------------------------
' prince

输出:

If someone loves a flower, of which just one single blossom grows in all the
millions and millions of stars, it is enough to make him happy just to

look at

the stars. He can say to himself, "Somewhere, my flower is there…" But if the
sheep eats the flower, in one moment all his stars will be darkened… And you think that is not important!

抑或能够在第3行从前插入:

sed '3i
--------------------------
 ' prince

输出:

If someone loves a flower, of which just one single blossom grows in all the
millions and millions of stars, it is enough to make him happy just to

look at

the stars. He can say to himself, "Somewhere, my flower is there…" But if the
sheep eats the flower, in one moment all his stars will be darkened… And you think that is not important!

我们来测试下文件是还是不是真正尚未增进到方式空间,因为形式空间中的内容暗中认可是会打字与印刷到荧屏的:

sed -n '2a
---------------------------
' prince

输出:


由此-n参数来遏制输出后发觉插入的剧情仍然被输出,所以可以看清插入的从头到尾的经过从未被增添到格局空间。

行使行替换命令将第2行到最终朝气蓬勃行的剧情总体替换来'----':

sed '2,$c
---------------------------
' prince

输出:

If someone loves a flower, of which just one single blossom grows in all

the

 

4. 打字与印刷命令: p/l/=

这里纯粹的打字与印刷命令应该是指p,可是因为后两个(l和=卡塔尔(英语:State of Qatar)和p大概,並且相对都比较轻易,所以这里放到一齐介绍。

[address]p
[address]=
[address]l

p命令用于打字与印刷格局空间的剧情,举例打字与印刷文件的率先行:

sed -n '1p' prince
==> If someone loves a flower, of which just one single blossom grows in all the

l命令雷同p命令,可是会来得调控字符,这些命令和vim的list命令相像,比如:

echo "column1 column2 column3^M" | sed -n 'l'
==> column1tcolumn2tcolumn3r$

=命令展现当前进行号,比方:

sed '=' prince
==>
1
If someone loves a flower, of which just one single blossom grows in all the 
2
millions and millions of stars, it is enough to make him happy just to look at 
3
the stars. He can say to himself, "Somewhere, my flower is there…" But if the 
4
sheep eats the flower, in one moment all his stars will be darkened… And you think that is not important!
5

 

5. 转移命令: y

更动命令的语法是:

[address]y/SET1/SET2/

它的功效是在相当的行上,将SET1中冒出的字符替换到SET第22中学对应地方的字符,比如1,3y/abc/xyz/会将1到3行中冒出的a替换到x,b替换到y,c替换到z。是否以为这几个效果很纯熟,其实那或多或少和tr命令是如出风流罗曼蒂克辙的。能够透过y命令将小写字符替换来大写字符,可是命令相比较长:

echo "hello, world" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
==> HELLO, WORLD

 

6. 取下大器晚成行命令: n

语法:

[address]n

n命令为将下生龙活虎行的剧情提前读入,並且将事情发生前读入的行(在情势空间中的行)输出到显示屏,然后继续的命令会应用到新读入的行上。因而n命令也会同d命令相仿更改sed的调控流程。

cat text

==>

.H1 ``"On Egypt"

Napoleon, pointing to the Pyramids, said to his troops:

"Soldiers, forty centuries have their eyes upon you."

当今要将.H1前面的空行删除:

sed '/.H1/{n;/^$/d}' text
==>
.H1 "On Egypt"
Napoleon, pointing to the Pyramids, said to his troops:
"Soldiers, forty centuries have their eyes upon you."

 

7.  读写文件命令: r/w

语法是:

[line-address]r file
[address]w file

读命令将内定的文书读取到相称行之后,并且输出到荧屏,这一点类似追加命令(a卡塔尔。大家以书中的例子来说课读文件命令。假若有四个文书text:

cat text
==> 
For service, contact any of the following companies:
[Company-list]
Thank you.

并且我们有贰个暗含集团名称列表的文书company.list:

cat company.list 
==>
Allied
Mayflower
United

方今我们要将company.list的从头到尾的经过读取到[Company-list]之后:

sed '/^[Company-list]/r company.list' text
=>
For service, contact any of the following companies:
[Company-list]
Allied
Mayflower
United
Thank you.

写命令将相称地址的具有行输出到钦赐的文书中。即便有三个文书内容如下,前半部分是真名,后半某些是区域名称:

cat text 
==>
Adams, Henrietta Northeast
Banks, Freda South
Dennis, Jim Midwest
Garvey, Bill Northeast
Jeffries, Jane West
Madison, Sylvia Midwest
Sommes, Tom South

到现在大家要将不相同区域的人名字写到分化的文件中:

sed '/Northeast$/w region.northeast
/South$/w region.south
/Midwest$/w region.midwest
/West$/w region.west' text
==>
Adams, Henrietta Northeast
Banks, Freda South
Dennis, Jim Midwest
Garvey, Bill Northeast
Jeffries, Jane West
Madison, Sylvia Midwest
Sommes, Tom South

 

8. 脱离命令: q

语法:

[line-address]q

当sed读取到格外的行之后即退出,不会再读入新的行,而且将眼下方式空间的剧情输出到荧屏。举例打字与印刷前3行内容:

sed '3q' prince
==>
If someone loves a flower, of which just one single blossom grows in all the 
millions and millions of stars, it is enough to make him happy just to look at 
the stars. He can say to himself, "Somewhere, my flower is there…" But if the

打字与印刷前3行也得以用p命令:

sed -n '3p' prince

然则对于大文件来讲,前边一个比后面一个功效越来越高,因为后边三个读取到第N行未来就退出了。前者就算打字与印刷了前N行,但是后续的行照旧要继续读入,只不会不作管理。

到此甘休,sed底子命令的部分就介绍完了。

 

六、小结

Linux系统工具众多,功效也相互重复,这么些重复部分的语法还各不相似,比方grep awk sed 都有正则表明式相配的功力,不过三者的正则表明式语法就不相符。每一种工具还分 GNU 版和不是 GNU 版,之间的出入也一点都不小,尽管都以 GNU 版,那么版本号的细微差异也会带给好些个出入。

在平凡的行管理职务方面,用sed很好,因为命令很简短。

 

七、参考

SED入门

Sed and awk 笔记之 sed 篇:简介

awk&sed!!!

(完)

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。