Linux sed 命令

2015-08-29 创建

1、概述

  sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

2、命令格式

  sed [OPTION]... {script-only-if-no-other-script} [input-file]...

  或者可以理解为:sed  [options]  'AddressCommand'  file ...

Address:

0、first~step
	删除first,每次步长step都删除
1、StartLine,EndLine
	比如1,100			
	$:最后一行
2、/RegExp/
	/root/
3、/pattern1/,/pattern2/
	第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
4、LineNumber
	指定的行
5、StartLine, +N
	从startLine开始,向后的N行;

Command:

d: 删除符合条件的行;
p: 显示符合条件的行;
a \string: 在指定的行后面追加新行,内容为string    # 新行
	\n:可以用于换行
i \string: 在指定的行前面添加新行,内容为string    # 新行
r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中; 
s/pattern/string/   默认只替换每行中第一次被模式匹配到的字符串
		【pattern 代表可以使用正则表达式】
	加修饰符
	g: 全局替换			s/pattern/string/g【修饰符】
	i: 忽略字符大小写	s/pattern/string/i【修饰符】
s///: s###, s@@@	效果一样
	\(\), \1, \2
		
l..e: like-->liker
		love-->lover
				  
		like-->Like
		love-->Love
	
&  引用模式匹配整个串

3、常用命令参数

  -n, --quiet, --silent    抑制模式空间的自动打印

[oldboy@moban sed]$ cat sed1 
qwewq
zhang liang
werwet bbb
ewtew 123
[oldboy@moban sed]$ sed '/bbb/p' sed1     # 打印模式控件内容和匹配内容
qwewq
zhang liang
werwet bbb
werwet bbb			# 重复内容
ewtew 123
[oldboy@moban sed]$ sed -n '/bbb/p' sed1  # 不打印模式空间内容,只打印匹配内容
werwet bbb
   -e script, --expression=script   将脚本添加到要执行的命令。 允许多点编辑。

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet bbb
ewtew 123
ettte
[oldboy@moban sed]$ sed -e '1,3d' sed1 
zhang liang
werwet bbb
ewtew 123
ettte
[oldboy@moban sed]$ sed -e '1,3d' -e 's/zhang/bing/' sed1 # 第一个是删除1到3行,第二个是将'zhang'替换为'bing'
bing liang
werwet bbb
ewtew 123
ettte

  -f script-file, --file=script-file    添加脚本文件内容到将要执行的命令。示例如下

[oldboy@moban sed]$ cat script1    # 没有引号
1,3d 			# 删除1到3行
s/zhang/bing/	# 每行中把 zhang 替换为 bing
/liang/p		
# 行中出现liang 的打印出来【不能使用 -n /liang/p,或者 n /liang/p。因为这是脚本不支持 命令选项】
[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet bbb
ewtew 123
ettte
[oldboy@moban sed]$ sed -f ./script1 sed1 
bing liang
bing liang
werwet bbb
ewtew 123
ettte
   -i[SUFFIX], --in-place[=SUFFIX]    直接修改读取的档案内容,而不是由屏幕输出。

[oldboy@moban sed]$ cat sed1 
zhang liang
werwet bbb
[oldboy@moban sed]$ sed -i s/bbb/liangzhuang/g sed1 
[oldboy@moban sed]$ cat sed1 
zhang liang
werwet liangzhuang
  --posix    禁用所有的GNU扩展。

  -r, --regexp-extended    在脚本中使用扩展正则表达式。

  -s, --separate    把文件视为单独的,而不是作为一个连续的长流。

  -u, --unbuffered    从输入文件中加载最小量的数据,并经常刷新输出缓冲区。

    如果没有 -e, --expression, -f, 或 --file 选项,然后第一个非选项参数为sed脚本解释。所有余下的参数都是输入文件的名称,如果没有指定的输入文件,则该标准输入被读取。

  
命令概要

Zero- or One- address commands 0个、1个 地址匹配  

=    打印当前行行号【sed -n '3,$ {=;p}' sed1   或者  sed -n '1,${=;p}' sed1 | sed -n '/^[0-9]*$/{N;s/\n/: /p}'

[oldboy@moban sed]$ cat sed1        
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed -n '3,$p' sed1   
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed -n '3,$=' sed1   # 打印行号
3
4
5
6
7
另外

[oldboy@moban sed]$ sed -n '3,$ {=;p}' sed1   
3
5555
4
zhang liang
5
werwet wqeqqq
6
ewtew 123
7
ettte
[oldboy@moban sed]$ sed -n '1,${=;p}' sed1 | sed -n '/^[0-9]*$/{N;s/\n/: /p}'     
1: qwewq
2: wetwdgh
3: 5555
4: zhang liang
5: werwet wqeqqq
6: ewtew 123
7: ettte
   a \string    在指定的行后面追加新行,内容为string   【\n:可以用于换行】

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed '/^e/a \### hello World!' sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
### hello World!
ettte
### hello World!
<pre name="code" class="java">[oldboy@moban sed]$ sed '/^e/a \### hello \nWorld!' sed1   # 添加了 \n
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
### hello 
World!
ettte
### hello 
World!

   
 i \string    在指定的行前面添加新行,内容为string 
[oldboy@moban sed]$ sed '/^e/i \### hello World!' sed1  
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
### hello World!
ewtew 123
### hello World!
ettte

  q [exit-code]      注意:不接受多行 【sed ’2,5 q’  filename   是不正确的】

  Q [exit-code]     注意:不接受多行  【sed ’2,5 Q’  filename   是不正确的】

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed '4q' sed1   # 打印第4行后退出  【sed '4q12' sed1】
qwewq
wetwdgh
5555
zhang liang
[oldboy@moban sed]$ sed '4Q' sed1  # 到第4行就退出     【sed '4Q12' sed1】
qwewq
wetwdgh
5555

  r filename    追加从 filename 中读取的文本

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ cat script1 
1,3d 
s/zhang/bing/
n /liang/p
[oldboy@moban sed]$ sed '/^e/r script1' sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123               # 第一次追加
1,3d 
s/zhang/bing/
n /liang/p
ettte                   # 第二次追加
1,3d 
s/zhang/bing/
n /liang/p
  R filename    从filename 中读取一行进行追加。每次读取一行内容。

[oldboy@moban sed]$ sed '/^e/R script1' sed1    # 请注意和 r 的区别
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123            # 第一次追加
1,3d                    # filename 的第一行
ettte                # 第二次追加
s/zhang/bing/           # filename 的第二行


Commands which accept address ranges   命令可以接受地址范围

  c \string    替换匹配的行,内容为string

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed '2,4 c \### kjkjkjk\nggggg' sed1   # 替换2到4行内容  # \n 换行
qwewq
### kjkjkjk
ggggg
werwet wqeqqq
ewtew 123
ettte
   d    删除模式空间内容

[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed '3,$ d' sed1 
qwewq
wetwdgh
  h H    将 pattern buffer 追加到 hold buffer 【h 拷贝, H 追加】

  g G    g 用 hold buffer 的内容拷贝到 pattern buffer 的内容 , 而 G 将 hold buffer 内容追加到 pattern buffer 【g 拷贝, G 追加】

  x    将 pattern buffer 放入 hold buffer, 而将 hold buffer 的内容输出 , pattern buffer 的内容变成下一行 

  l    列出当前行的【全部信息】 小写的【L】

[oldboy@moban sed]$ sed -n '3,5 l' sed1 
5555$
zhang liang$
werwet wqeqqq$
  l width    列出当前行的全部信息,如果字符长度为 width 时,那么被打断在下一行显示。这是一个GNU扩展。

[oldboy@moban sed]$ sed -n '3,5 l 10' sed1    # 一个空格也会算作一个字符【第10个时被打断,第10个字符在下一行显示】
5555$
zhang lia\
ng$
werwet wq\
eqqq$
  n N    读取【n】/追加【N】 下一行的输入到模式空间。

[oldboy@moban sed]$ sed -n '2,5 {n;p}' sed1  
5555
werwet wqeqqq
[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang    liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed -n '2,2 {N;p}' sed1   # 这些现象还有些不理解
wetwdgh
5555
[oldboy@moban sed]$ sed -n '2,3 {N;p}' sed1  
wetwdgh
5555
[oldboy@moban sed]$ sed -n '2,4 {N;p}' sed1  
wetwdgh
5555
zhang    liang
werwet wqeqqq
[oldboy@moban sed]$ sed -n '2,5 {N;p}' sed1  
wetwdgh
5555
zhang    liang
werwet wqeqqq
[oldboy@moban sed]$ sed -n '2,2 {n;p}' sed1  # 这些现象还有些不理解
5555
[oldboy@moban sed]$ sed -n '2,3 {n;p}' sed1   
5555
[oldboy@moban sed]$ sed -n '2,4 {n;p}' sed1  
5555
werwet wqeqqq
[oldboy@moban sed]$ sed -n '2,5 {n;p}' sed1  
5555
werwet wqeqqq
   p    打印当前模式空间内容。

  P  命令输出 pattern buffer 中第一个换行符之前的内容

  w filename    当前模式空间的内容写入到 filename 中。

[oldboy@moban sed]$ ll
total 8
-rw-rw-r-- 1 oldboy oldboy 31 Sep  4 07:40 script1
-rw-rw-r-- 1 oldboy oldboy 64 Sep 14 23:21 sed1
[oldboy@moban sed]$ cat sed1 
qwewq
wetwdgh
5555
zhang    liang
werwet wqeqqq
ewtew 123
ettte
[oldboy@moban sed]$ sed -n '3,5 w ztest' sed1 
[oldboy@moban sed]$ ll
total 12
-rw-rw-r-- 1 oldboy oldboy 31 Sep  4 07:40 script1
-rw-rw-r-- 1 oldboy oldboy 64 Sep 14 23:21 sed1
-rw-rw-r-- 1 oldboy oldboy 34 Sep 14 23:47 ztest
[oldboy@moban sed]$ cat ztest 
5555
zhang    liang
werwet wqeqqq
  W filename    将当前模式空间的第一行写入filename。这是一个GNU扩展。

[oldboy@moban sed]$ sed -n '3,5 W ztest2' sed1   # 不知道这个模式空间的第一行是怎么定义的????
[oldboy@moban sed]$ cat ztest2
5555
zhang    liang
werwet wqeqqq
   s/regexp/replacement/   默认只替换每行中第一次被模式匹配到的字符串 【s/pattern/string/    pattern 代表可以使用正则表达式】

加修饰符
	g: 全局替换		s/pattern/string/g【修饰符】
	i: 忽略字符大小写	s/pattern/string/i【修饰符】
s///: s###, s@@@	效果一样    【\(\), \1, \2  分组】【&  引用模式匹配整个串】
        示例:

[oldboy@moban ~]$ cat /etc/fstab 
UUID=67be2fce-cfc2-4e9e-ae0f-47d70d2d4bad /boot                   ext4    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
[oldboy@moban ~]$ sed 's@/@##@' /etc/fstab 
UUID=67be2fce-cfc2-4e9e-ae0f-47d70d2d4bad ##boot                   ext4    defaults        1 2
tmpfs                   ##dev/shm                tmpfs   defaults        0 0
devpts                  ##dev/pts                devpts  gid=5,mode=620  0 0
[oldboy@moban ~]$ sed 's@/@##@g' /etc/fstab 
UUID=67be2fce-cfc2-4e9e-ae0f-47d70d2d4bad ##boot                   ext4    defaults        1 2
tmpfs                   ##dev##shm                tmpfs   defaults        0 0
devpts                  ##dev##pts                devpts  gid=5,mode=620  0 0
[oldboy@moban ~]$ 
[oldboy@moban ~]$ sed 's@u@##@g' /etc/fstab  
UUID=67be2fce-cfc2-4e9e-ae0f-47d70d2d4bad /boot                   ext4    defa##lts        1 2
tmpfs                   /dev/shm                tmpfs   defa##lts        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
[oldboy@moban ~]$ sed 's@u@##@gi' /etc/fstab  
####ID=67be2fce-cfc2-4e9e-ae0f-47d70d2d4bad /boot                   ext4    defa##lts        1 2
tmpfs                   /dev/shm                tmpfs   defa##lts        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

l..e:   like-->liker
	love-->lover
				  
	like-->Like
	love-->Love
[oldboy@moban sed]$ cat sed2
hello, like
hi, my love
[oldboy@moban sed]$ sed 's/l..e/l..er/' sed2
hello, l..er
hi, my l..er
[oldboy@moban sed]$ sed 's/l..e/&r/' sed2      # 使用了 &
hello, liker
hi, my lover
[oldboy@moban sed]$ sed 's/\(l..e\)/\1r/' sed2    # 使用了向后引用 或者扩展正则: sed -r 's/(l..e)/\1r/' sed2
hello, liker
hi, my lover

地址

    sed 命令可以不给地址,那么命令对所有行有效。如果有了地址,那么匹配的地址行将会执行命令。

    关于地址范围要注意的三件事:1、语法是addr1,addr2 (地址是用逗号分隔的);addr1 总是被接受,尽管有 addr2 选择行更靠前一些;如果addr2是正则表达式,那么他不会再次匹配addr1。

数据准备

[oldboy@moban sed]$ cat sed1
qwewq
wetwdgh
5555
zhang    liang
werwet wqeqqq
ewtew 123
ettte

    支持一下地址类型:

  number    支持特定行number 匹配。

[oldboy@moban sed]$ sed -n '4p' sed1  
zhang    liang
   first~step    从first 开始匹配,步长为step , 其中 first 可以为0。

[oldboy@moban sed]$ sed -n '1~3p' sed1  
qwewq
zhang    liang
ettte
[oldboy@moban sed]$ sed -n '0~3p' sed1
5555
ewtew 123
   $    匹配最后一行

[oldboy@moban sed]$ sed -n '4,$p' sed1   
zhang    liang
werwet wqeqqq
ewtew 123
ettte
   /regexp/    根据正则表达式匹配

[oldboy@moban sed]$ sed -n '/^e/p' sed1  # 以 e开头的行匹配
ewtew 123
ettte
   \cregexp c   根据正则表达式匹配,c 可以是任意字符

[oldboy@moban sed]$ sed -n '\Q^eQp' sed1    
ewtew 123
ettte
  addr1,+N    匹配行 addr1 和接下来的N 行。

[oldboy@moban sed]$ sed -n '3,+2p' sed1
5555
zhang    liang
werwet wqeqqq
  

4、常用示例

一、

# sed "2,4d" /etc/fstab
# sed '3,$d' /etc/fstab 	// 注意:sed "3,$d" /etc/fstab	【出错】
# sed '2,+3d' /etc/fstab	// 删除第二行,和接下来的3行
# sed '3d' /etc/fstab		// 删除第三行
# sed '/^\//d' /etc/fstab	// 删除以 / 开头的行
二、

# sed '/fs/a \@@@ dgfeeg wert' /etc/fstab
# sed '/fs/a \### hello world.\n@@@ HellO WORLD!!' /etc/fstab		// \n 用于换行
# sed '/fs/i \@@@ werwe.\n!!!wer wetwet' /etc/fstab
# sed '2r /etc/issue' /etc/fstab
# sed '2,3r /etc/issue' /etc/fstab
# sed '/fs/w /tmp/fs.txt' /etc/fstab
# sed 's/fs/FSS/' /etc/fstab
# sed 's/^\//#/' /etc/fstab		// 表示行首的 / 换位 #
# sed 's/\//@/g' /etc/fstab
# sed 's@/@###@g' /etc/fstab	// 把 / 全局替换为 ###

# sed 's/l..e/l..er/' sedtest.txt	// 注意结果
# sed 's/l..e/&r/g' sedtest.txt 
# sed 's/\(l..e\)/\1r/' sedtest.txt 
# sed 's/l\(..e\)/L\1/' sedtest.txt		// like-->Like 	love-->Love

三、

1、删除/etc/grub.conf文件中行首的空白符;
# sed -r 's@^[[:space:]]+@@g' /etc/grub.conf
2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;
# sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\2@g' /etc/inittab
3、删除/etc/inittab文件中的空白行;
# sed '/^$/d' /etc/inittab
4、删除/etc/inittab文件中开头的#号; 
# sed 's@^#@@g' /etc/inittab
5、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符;
# sed -r 's@^#[[:space:]]+@@g' /etc/inittab
6、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#
# sed -r 's@^[[:space:]]+#@@g' /etc/inittab
7、取出一个文件路径的目录名称; 				【/etc/rc.d/we/werdg/】 【结果:/etc/rc.d/we/】
echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g'
  解析:^(/.*/)  [^/]+【匹配不是 / 的字符,有一个或则多个】   /?【是否以/结尾】
基名:										【/etc/rc.d/we/werdg/】 【结果:werdg】
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g'	

5、命令所在位置和类型

[oldboy@moban sed]$ which sed
/bin/sed
[oldboy@moban sed]$ type sed
sed is hashed (/bin/sed)

6、另请参见

    linux sed命令详解

    linux sed命令详解



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值