shell脚本中sed的使⽤
Shell脚本之sed篇
原创作品,允许转载,转载时请务必以超链接形式标明⽂章、作者信息和本声明。否则将追究法律责任。
⽬录:
⼀、概述
⼆、sed基本语法格式
三、简单正则表达式
四、sed脚本指令(注释、替换、删除、追加、打印、下⼀⾏、读写⽂件、退出、多⾏模式)
五、综合案例
⼀、概述
1.sed是⼀款流编辑⼯具,⽤来对⽂本进⾏过滤与替换⼯作,特别是当你想要对⼏⼗个配置⽂件做统计修改时,你会感受到sed的魅⼒!  sed通过输⼊读取⽂件内容,但⼀次仅读取⼀⾏内容进⾏某些指令处理后输出,所以sed更适合于处理⼤数据⽂件。
2.sed流程:
* 通过⽂件或管道读取⽂件内容。
* sed并不直接修改源⽂件,⽽是将读⼊的内容复制到缓冲区中,我们称之为模式空间(pattern space)。
* 根据sed的指令对模式空间中的内容进⾏处理并输出结果,默认输出⾄标准输出即屏幕上。
输⼊
------------------------------------------------
|
|
v
v
读取⼀⾏内容,并复制到模式空间    <------------ sed 指令
|
|
v
v
------------------------------------------------
输出经过处理后的内容
*****************************************************************************************************
⼆、sed基本语法结构
sed    [script]  []
sed  选项...      [脚本指令]      [输⼊⽂件]
如果没有输⼊⽂件,则sed默认对标准输⼊进⾏处理(即键盘输⼊)。脚本指令是第⼀个不以“-”开始的参数。
1.选项含义:
--version            显⽰sed版本。
--help              显⽰帮助⽂档。
-n,--quiet,--silent    静默输出,默认情况下,sed程序在所有的脚本指令执⾏完毕后,将⾃动打印
模式空间中的内容,这些选项可以屏蔽⾃动打印。
-e script              允许多个脚本指令被执⾏。
-f script-file,
--file=script-file        从⽂件中读取脚本指令,对编写⾃动脚本程序来说很棒!
-i,--in-place        直接修改源⽂件,经过脚本指令处理后的内容将被输出⾄源⽂件(源⽂件被修改)
慎⽤!
-l N, --line-length=N    该选项指定l指令可以输出的⾏长度,l指令⽤于输出⾮打印字符。
--posix            禁⽤GNU sed扩展功能。
-r, --regexp-extended
在脚本指令中使⽤扩展正则表达式
-s, --separate        默认情况下,sed将把命令⾏指定的多个⽂件名作为⼀个长的连续的输⼊流。
⽽GNU sed则允许把他们当作单独的⽂件,
这样如正则表达式则不进⾏跨⽂件匹配。
-u, --unbuffered      最低限度的缓存输⼊与输出。
2.简单案例:
以上仅是sed程序本⾝的选项功能说明,⾄于具体的脚本指令(即对⽂件内容做的操作)后⾯我们会详细描述,
这⾥就简单介绍⼏个脚本指令操作作为sed程序的例⼦。
a,append        追加
i,insert        插⼊
d,delete        删除
s,substitution  替换
案例说明:灰⾊背景的内容为待处理的源⽂件,红⾊字体的⽂字为sed脚本,蓝⾊字体的⽂字为处理后的结果输出。
这⾥为样本⽂件:
[jacob@localhost ~] #cat 
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
[jacob@localhost ~] #sed  '2a TYPE=Ethernet'      第⼆⾏后添加TYPE=Ethernet
[jacob@localhost ~] #sed  '3i  TYPE=Ethernet'    第三⾏前添加TYPE=Ethernet
[jacob@localhost ~] #sed  's/yes/no/g'          将样本⽂件中的所有yes替换为no
[jacob@localhost ~] #sed  '3,4d'                  删除第3⾄4⾏的内容
以上⼤多数操作指令,都依据⾏号定位操作对象(地址),如:2a即第⼆⾏后添加。
但实际情况可能⼤多数情况你并不确定你要操作对象(地址)的⾏号,这时更多的我们会使⽤正则表达式确定操作对象(地址)。下⾯是使⽤正则表达式定位操作⾏的⽰例:
[jacob@localhost ~] #sed  '/ONBOOT/a TYPE=Ethernet' 
匹配到包含ONBOOT的⾏,并在其后添加TYPE=Ethernet
[jacob@localhost ~] #sed  '/^GATEWAY/d' 
匹配以GATEWAY开始的⾏,并删除改⾏
另外我们的操作指令可以,写⼊到脚本⽂件中并通过sed的-f选项读取。
创建⼀个sed脚本,内容如下:
[jacob@localhost ~] #cat  sed.sh
/^$/d                                    这条指令的作⽤是:匹配到空⽩⾏后,删除改⾏。
[jacob@localhost ~] #sed  -f  sed.sh      对⽂件执⾏sed.sh指令
另外,当你需要执⾏多个指令时,可以使⽤以下三种⽅法:
1. [jacob@localhost ~] #sed  's/yes/no/;s/static/dhcp/'              注:使⽤分号隔开指令。
2. [jacob@localhost ~] #sed  -e  's/yes/no/'    -e  's/static/dhcp/'      注:使⽤-e选项。
3. [jacob@localhost ~] #sed '
>s/yes/no/
>s/static/dhcp/'                                      注:利⽤分⾏指令。
然⽽在命令⾏上输⼊过长的指令是愚蠢的,这时就需要-f选项指定sed脚本⽂件,在脚本⽂件中可以包含多⾏指令,⽽且便于修改!
*****************************************************************************************
三、简单正则表达式
从以上案例中我们不难发现,我们编写的脚本指令需要指定⼀个地址来决定操作范围,如果不指定则默认对⽂件的所有⾏操作。如:sed  'd'          将删除的所有⾏,⽽'2d'则仅删除第⼆⾏。
1.为sed指令确定操作地址:
number        指定输⼊⽂件的唯⼀⾏号。
first~step    以first开始,并指定操作步长为step,如1~2,指定第⼀⾏,第三⾏,第五⾏... 为操作地址。
[jacob@localhost ~] #sed  -n  '1~2p'          打印⽂件的奇数⾏。
2~5,则可以指定第⼆⾏开始,每5⾏匹配⼀次操作地址。
$            匹配⽂件的最后⼀⾏。
/regexp/    //中间包含的是正则表达式,通过正则表达式匹配操作地址。
注://空的正则表达式,匹配最近⼀次正则表达式的匹配地址,会在后⾯使⽤看出效果。
\cregexpc    匹配扩展正则表达式,c字符可以使⽤任意字符替代。
addr1,addr2    匹配从操作地址1到操作地址2的所有⾏。
[jacob@localhost ~] #sed  '2,8d'          删除2⾄8中间的所有⾏。
addr1,+N        匹配地址1以及后⾯的N⾏内容。
2.正则表达式概述(对你要内容的⼀种描述)
char            字符本⾝就匹配字符本⾝,如/abc/就是定位包含abc的⾏。
*            匹配前⾯表达式出现了0或若⼲次,如/a*/可以帮你到a,aa,aaa,... ...等等。
\+            类似于*,但匹配前⾯表达式的1次或多次,这属于扩展正则表达式。
\?            类似于*,但匹配前⾯表达式的0次或1次,这属于扩展正则表达式。
\{i\}        类似于*,但匹配前⾯表达式的i次(i为整数),如:a\{3\}可以帮你到aaa。
\{i,j\}      匹配前⾯表达式的i到j次,如a\{1,2\}可以帮你到a或aa或aaa。
\{i,\}        匹配前⾯表达式⾄少i次。
\( \)        将\( \)内的模式存储在保留空间。最多可以存储9个独⽴⼦模式,可
通过转义\1⾄\9重复保留空间的内容⾄此点。
\n            转义\1⾄\9重复保留空间的内容⾄此点。
例:的内容为ssttss
grep '\(ss\)tt\1'             \1表⽰将ss重复在tt后⾯
该grep命令等同于grep  ssttss      在⽂件中ssttss
.            (点)匹配任意字符。
^            匹配⾏的开始,如^test    将匹配所有以test开始的⾏。
$            匹配⾏的结尾,如test$    将匹配所有以test结尾的⾏。
[]          匹配括号中的任意单个字符,如a[nt]    将匹配an或at。
[^]          匹配不包含在[]中的字符,如[^a-z]    将匹配除a-z以外的字符。
\n          匹配换⾏符。
\char        转义特殊字符,如\*,就是匹配字⾯意义上的星号。
**************************************************************************************
四、sed脚本指令
常⽤的sed脚本指令有:
*注释(#)
*替换(s)
*删除(d)
*追加(a)
*插⼊(i)
*更改(c)
*列印(l)
*转换(y)
*打印(p)
*读写⽂件(r,w)
*退出(q)
*下⼀步(n)
*Next(N)
*Print(P)
*Delete(D)
*Hold(h,H)
*Get(g,G)
*branch,test
sed脚本指令的基本格式:
[address]command
[地址]命令备注:有些命令仅可以对⼀⾏操作,有些可以对多⾏操作。
命令可以⽤⼤括号进⾏组合以使命令序列可以作⽤于同⼀个地址:
address{
command1
command2
command3
}
第⼀个命令可以和左⼤括号在同⼀⾏,但右⼤括号必须单独处于⼀⾏。
注意事项:命令后添加空格会产⽣错误。
1.注释(#):
注释⾏是以#开始的⾏,如果#后⾯的字符为n,则屏蔽sed程序的⾃动输出功能,等同于命令选项-n。
2.替换(s,Substitution):
[address]s/pattern/replacement/flags
address为操作地址,s为替换指令,/pattern/匹配要替换的内容,/replacement/为替换的内容。
flags可以是:
n  1⾄512之间的数字,表⽰对模式空中指定模式的第n次出现进⾏替换。
如⼀⾏中有3个A,⽽只想替换第⼆个A。
g  对模式空间的匹配进⾏全局更改。没有g则仅第⼀次匹配被替换,如⼀⾏中有3个A,则仅替换第⼀个A。        p  打印模式空间的内容。
w  file
将模式空间的内容写到⽂件file中。
replacement为字符串,⽤来替换与正则表达式匹配的内容。
在replacement部分,只有下列字符有特殊含义:
&    ⽤正则表达式匹配的内容进⾏替换。
\n  匹配第n个⼦串,这个⼦串之前在pattern中⽤\( \)指定。
\    转义(转义替换部分包含的:&, \等)。
-----------------------------------------------------------------------------------------------
⽰例1所使⽤的样本⽂件为:
[jacob@localhost ~] #cat 
<html>
<title>First Web</title>
<body>Hello the World! <body>
</html>
⽰例1:将样本⽂件中的第⼆个<body>替换为</body>
编写sed脚本为:
[jacob@localhost ~] #cat  sed.sh
/body/{
s//\/body/2              注:替换与⾏匹配相同的内容即body,替换为/body,但仅替换第⼆个body为/body。
}
执⾏sed程序的结果:
[jacob@localhost ~] #sed  -f  sed.sh 
<html>
<title>First Web</title>
<body>Hello the World!</body>
</html>
---------------------------------------------------------------------------------------------
⽰例2所使⽤的样本⽂件为:
[jacob@localhost ~] #cat 
<html>
<title>First Web</title>
<body>
h1Helloh1
h2Helloh2
h3Helloh3
</body>
</html>
⽰例2:给所有第⼀个的h1,h2等添加<>;第⼆个h1,h2添加</>
编写sed脚本为:
[jacob@localhost ~] #cat  sed.sh
/h[0-9]/{          注:匹配h紧跟⼀个数字的⾏
s//\<&\>/1        注:替换与上⼀⾏中匹配内容相同的内容,即替换h[0-9],替换为<&>,其中&即前⾯要替换的内容。s//\<\/&\>/2      注:上⼀条指令仅替换第⼀个,本⾏指令⽤来替换第⼆个。
}
shell最简单脚本
执⾏sed程序的结果:
[jacob@localhost ~] #sed  -f  sed.sh 
<h1>Hello</h1>
<h2>Hello</h2>
<h3>Hello</h3>
---------------------------------------------------------------------------------------------
技巧:关于 's///' 命令的另⼀个妙处是 '/' 分隔符有许多替换选项。
如果规则表达式或替换字符串中有许多斜杠,则可以通过在 's' 之后指定⼀个不同的字符来更改分隔符。
⽰例:$ sed -e 's:/usr/local:/usr:g'         这⾥:为分隔符。
3.删除(d ,delete):
删除指令删除匹配的⾏,⽽且删除命令还会改变sed脚本中命令的执⾏顺序。因为:
匹配的⾏⼀旦被删除,模式空间将变为“空”,⾃然不会再执⾏sed脚本后续的命令。
删除命令将导致读取新的输⼊⾏(下⼀⾏),⽽sed脚本中的命令则从头开始执⾏。
注意事项:删除将删除整个⾏,⽽不只是删除匹配的内容。(如要删除匹配的内容,可以使⽤替换)
⽰例1所使⽤的样本⽂件为:
[jacob@localhost ~] #cat 
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254
⽰例1:删除⽂件中的空⽩⾏
编写sed脚本为:
[jacob@localhost ~] #cat  sed.sh
/.*/{
/^$/d
}
执⾏sed程序的结果:
[jacob@localhost ~] #sed  -f  sed.sh 
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。