linux-sed命令

第1章 sed基础

第1章 sed知识点

1.1 sed的选项  stream editor 流编辑器

 -r              支持扩展正则

 -n              取消默认输出

 -i               直接修改不输出到桌面

 -i.bak        备份

1.1 sed是什么

1.2 sed的书写格式

sed    ‘条件命令’

sed      ‘pattern命令’

sed      ‘模式命令’

字符流编辑器 Stream Editor

1.3 sed命令执行过程

1.读取文件内容第1行

2.是否满足条件

     1).满足条件 执行对应的命令 p  s  d 

     2).不满足   继续第1步

3.截止到文件的最后一行

sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

第2章 sed命令的使用

sed增删改查   不加i选项只会把修改内容输出到并没有真正修改,加上i选项会直接修改文件内容

1.2 sed功能与版本

1)处理纯文本文件,日志,配置文件等==>Linux

2)增加、删除、修改、查询

3)sed
–version

[root@oldboyedu43 ~]# sed –version

GNU sed version 4.2.1

Copyright (C) 2009 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,

to the extent permitted by law.

 

GNU sed home page: <http://www.gnu.org/software/sed/>.

General help using GNU software: <http://www.gnu.org/gethelp/>.

E-mail bug reports to: <bug-gnu-utils@gnu.org>.

Be sure to include the word “sed” somewhere in the “Subject:” field.

1.3 语法格式

sed [选项]
[sed指令] [输入文件]

sed -i.bak
‘s#oldboy#oldgirl#g’ oldboy.txt

-i
 —-sed命令的参数

s —sed指令

g
—小尾巴/修饰

2.1 sed 增加  cai

c   replace 替换

a   append 追加

i   insert 插入

1.4 sed 命令运行过程

sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern
space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

2.1.1 在person.txt文件第三行下追加12306,xiao,UFO

查看person.txt文件

[root@zeq lx]# cat person.txt

101,zeq,CEO

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

第三行下追加12306,xiao,UFO

[root@zeq lx]# sed '3a12306,xiao,UFO' person.txt      a追加,3a在第三行下追加

101,zeq,CEO

102,zhang,CTO

103,Love,COO

12306,xiao,UFO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

第2章 查询 p(print)

2.1.2 在person.txt文件第三行上插入12306,xiao,UFO

[root@zeq lx]# sed '3i12306,xiao,UFO' person.txt

101,zeq,CEO

102,zhang,CTO

12306,xiao,UFO

103,Love,COO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

2.1 按行查询

2.1.3 把person.txt文件第三行替换成12306,xiao,UFO

[root@zeq lx]# sed '3c12306,xiao,UFO' person.txt

101,zeq,CEO

102,zhang,CTO

12306,xiao,UFO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

2.1.1 单行

1.   p 打印模式空间的内容

2.   -n 取消默认的sed软件的输出

创建环境

[root@oldboyedu43 ~]# cd /oldboy/

[root@oldboyedu43 oldboy]# touch person.txt

[root@oldboyedu43 oldboy]# cat >>person.txt<<EOF

> 101,oldboy,CEO

> 102,zhangyao,CTO

> 103,Alex,COO

> 104,yy,CFO

> 105,feixue,CIO

> EOF

1: 取具体的某一行   sed -n ‘3p’ person.txt

[root@oldboyedu43 oldboy]# sed -n ‘3p’ person.txt

103,Alex,COO

2. 显示文件的最后一行  sed -n ‘$p’
person.txt

[root@oldboyedu43 oldboy]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO                                                                                                      

[root@oldboyedu43 oldboy]# sed -n ‘$p’ person.txt

105,feixue,CIO  

3. 取包含xxx的行

[root@oldboyedu43 oldboy]# sed -n ‘/oldboy/p’ person.txt 

101,oldboy,CEO

2.1.4 在文件最后一行增加

12306,xiao,UFO

12580,tao,XO

[root@zeq lx]# sed  '$a12306,xiao,UFO\n12580,tao,XO' person.txt    $最后一行   \n回车

101,zeq,CEO

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

12306,xiao,UFO

12580,tao,XO

2.1.2 多行

1. 连续的多行-地址范围精讲  连续的行使用 , 号

没有地址,默认匹配所有行

sed -n ‘从哪里来,哪里去p’

  数字 :sed -n ‘1,3p’ person.txt

[root@oldboyedu43 oldboy]# sed -n ‘1,3p’ person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

 2. 正则地址范围-模糊,容易找多了

 正则 :sed -n ‘/oldboy/p’ person.txt

          sed -n ‘/oldboy/,/yy/p’
person.txt

[root@oldboyedu43 oldboy]# sed -n ‘/oldboy/p’ person.txt

101,oldboy,CEO

[root@oldboyedu43 oldboy]# sed -n ‘/o.*y/p’ person.txt 

101,oldboy,CEO

[root@oldboyedu43 oldboy]##显示包含oldboy的行到包含yy的行

[root@oldboyedu43 oldboy]# sed -n ‘/oldboy/,/yy/p’ person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

3. 不连续的多行 使用 ; 号隔开(使用分号)

[root@oldboyedu43 oldboy]# #同一行放多个命令用;

[root@oldboyedu43 oldboy]# sed -n ‘1p;4p;5p’ person.txt 

101,oldboy,CEO

104,yy,CFO

105,feixue,CIO

2.2 sed 删除 d   

2.1.3 过滤多个字符

-r
支持扩展正则表达式

|
扩展正则,同时过滤多个字符

[root@oldboyedu43 oldboy]# sed -nr ‘/oldboy|yy/p’ person.txt 

101,oldboy,CEO

104,yy,CFO sed里面的正则字符左右必须有“/”

2.2.1 删除第2行到第5行

[root@zeq lx]# sed '2,5d' person.txt

101,zeq,CEO

110,ahao,COCO

第3章 增加

2.2.2 删除从yy开始的行到文件结尾的内容

[root@zeq lx]# sed   '/yy/,$d' person.txt             $文件结尾

101,zeq,CEO

102,zhang,CTO

103,Love,COO

3.1 单行增加

a
追加append,在指定行后添加一行或多行文本

i
插入insert,在指定行前添加一行或多行文本

[root@oldboyedu43 oldboy]# sed ‘$a 106,wuxingge,UFO’ person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

106,wuxingge,UFO

[root@oldboyedu43 oldboy]# sed ‘2i 106,wuxingge,UFO\n107,lee,XO’ person.txt

101,oldboy,CEO

106,wuxingge,UFO

107,lee,XO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2.2.3 删除包含ahao的行

[root@zeq lx]# sed '/ahao/d' person.txt

101,zeq,CEO

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

3.2 多行增加

换行符 \n

[root@oldboyedu43 oldboy]# sed ‘$a 106,wuxingge,UFO\n107,lee,XO’ person.txt 

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

106,wuxingge,UFO

107,lee,XO

注:cat 命令多行追加

  echo只能在追加到文件末尾
 echo
>>

  vim
可以写入

2.2.4 删除不包含ahao的行

[root@zeq lx]# sed '/ahao/!d' person.txt             !取反,排除

110,ahao,COCO

第4章 删除

2.3 sed 替换 ‘s###g’

4.1 单行删除

  d删除 delete

  $ 代表文件的最后一行

  ‘1d’  或 ‘/oldboy/d’

[root@oldboyedu43 oldboy]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO  

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu43 oldboy]# sed ‘/oldboy/d’ person.txt 

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2.3.1 替换掉所有的数字

[root@zeq lx]# sed 's#[0-9]##g'  person.txt

,zeq,CEO

,zhang,CTO

,Love,COO

,yy,CFO

,faker,CIO

,ahao,COCO

4.2 多行删除

[root@oldboyedu43 oldboy]# sed ‘1,4d’ person.txt 

105,feixue,CIO

2.3.2 替换掉每行中的第一个数字

[root@zeq lx]# sed 's#[0-9]##'  person.txt       sed 's#[0-9]##' 不加g,默认是匹配到每行第一个数字       sed 's#[0-9]##2' 匹配每行第二个数字

01,zeq,CEO

02,zhang,CTO

03,Love,COO

04,yy,CFO

05,faker,CIO

10,ahao,COCO

4.3 企业案例:不显示文件中的空行

1. sed ‘/^$/d’
person.txt

[root@oldboyedu43 oldboy]# sed -r ‘/^$/d’ person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2. grep -v ‘^$’ person.txt

[root@oldboyedu43 oldboy]# grep -v ‘^$’ person.txt 

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

3. awk ‘!/^$/’ person.txt

[root@oldboyedu43 oldboy]# awk ‘!/^$/’ person.txt 

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

4. sed -n ‘/^$/!p’ person.txt

[root@oldboyedu43 oldboy]# sed -n ‘/^$/!p’ person.txt 

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2.3.3 后向引用  取出ip地址

[root@zeq ~]# ifconfig eth0 |sed -rn '2s#^.*r:(.*)  Bc.*#\1#gp'

10.0.0.200

[root@zeq ~]# ifconfig eth0 |awk -F'[ :]+'   'NR==2{print $4}'

10.0.0.200

[root@zeq ~]# ifconfig eth0 |awk -F'addr:|  Bc'   'NR==2{print $2}'

10.0.0.200

[root@zeq ~]# ifconfig eth0 |awk -F'[^0-9.]+'   'NR==2{print $2}'

10.0.0.200

第5章 替换

2.4 sed  查

5.1 文本替换

2.4.1 显示文件的第5行

[root@zeq ~]# sed -n 5p person.txt

105,faker,CIO

5.1.1 sed -i ‘s#a#b#g’ oldboy.log

  s
  单独使用——>将每一行中第一个匹配的字符串进行替换

[root@oldboyedu43 oldboy]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu43 oldboy]# sed ‘s#[0-9]#oldboy#’ person.txt 

oldboy01,oldboy,CEO

oldboy02,zhangyao,CTO

oldboy03,Alex,COO

oldboy04,yy,CFO

oldboy05,feixue,CIO

   g
  global
每一行进行全部替换——>sed指令s的替换标志之一(全局替换)

[root@oldboyedu43 oldboy]# sed ‘s#[1-9]#AA#g’ person.txt

AA0AA,oldboy,CEO

AA0AA,zhangyao,CTO

AA0AA,Alex,COO

AA0AA,yy,CFO

AA0AA,feixue,CIO

2.4.2 显示文件的第2行到第5行

[root@zeq ~]# sed -n '2,5p' person.txt

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

5.1.2 修改文件 -i

  sed -i.bak
‘s#[1-9]#AA#g’ person.txt

  -i.bak  先把文件备份为 person.txt.bak ,然后再修改文件的内容

   -i   参数要放在sed所有参数最后面

sed -i.bak.$(date +%F)
‘s#[1-9]#AA#g’ person.txt

[root@oldboyedu43 oldboy]# sed -i.bak.$(date +%F) ‘s#[1-9]#AA#g’ person.txt

[root@oldboyedu43 oldboy]# cat person.txt

AA0AA,oldboy,CEO

AA0AA,zhangyao,CTO

AA0AA,Alex,COO

AA0AA,yy,CFO

AA0AA,feixue,CIO

[root@oldboyedu43 oldboy]# cat person.txt.bak.2018-01-12

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2.4.3 显示文件最后一行

[root@zeq ~]# sed -n '$p' person.txt

110,ahao,COCO

5.2 变量替换

2.4.4 显示文件中包含zeq的行

[root@zeq ~]# sed -n '/zeq/p' person.txt

101,zeq,CEO

5.2.1 变量替换

[root@oldboyedu43 oldboy]# a=oldboy    定义变量

[root@oldboyedu43 oldboy]# b=old       定义变量

[root@oldboyedu43 oldboy]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu43 oldboy]# sed "s#$a#$b#g" person.txt   sed使用变量

101,old,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

2.4.5 显示文件中从包含101的行到105的行

[root@zeq ~]# sed -n '/101/,/105/p' person.txt

101,zeq,CEO

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

5.2.2 引号的区别总结

1.单引号-所见即所得

[root@oldboyedu43 oldboy]# echo ‘stu{1..6},`pwd`’

stu{1..6},`pwd`

2.双引号-对特殊符号进行解析 $ $() “

[root@oldboyedu43 oldboy]# echo "stu{1..6},`pwd`"

stu{1..6},/oldboy

[root@oldboyedu43 oldboy]# echo "I’m aaa"

I’m aaa                                         

[root@oldboyedu43 oldboy]# echo ‘I’m aaa’

> ^C 想要显示单引号是需用双引号

3.不加引号和双引号一样,支持通配符{}*.txt

[root@oldboyedu43 oldboy]# echo stu{1..6},`pwd`

stu1,/oldboy stu2,/oldboy stu3,/oldboy stu4,/oldboy stu5,/oldboy stu6,/oldboy

4.反引号

[root@oldboyedu43 oldboy]# echo `pwd` ddd

/oldboy ddd

5.3 反向引用

()的功能可以禁止正则表达式的一部分

扩展正则,使用-r

\1引用第一个小括号中的匹配内容, \2引用第二个小括号中的匹配内容,sed最多可以记住9个

2.4.6 特殊写法:显示文件的第1和4行和5行

[root@zeq ~]# sed -n '1p ;4p; 5p' person.txt

101,zeq,CEO

104,yy,CFO

105,faker,CIO

5.3.1 预备知识——sed &

sed &前面正则匹配到的内容

[root@oldboyedu43 oldboy]# echo 123456|sed -r ‘s#([0-9])#<\1>#g’

<1><2><3><4><5><6>

[root@oldboyedu43 oldboy]# echo 123456|sed  ‘s#[0-9]#<&>#g’

<1><2><3><4><5><6>

[root@oldboyedu43 oldboy]# echo this is a test line | sed ‘s#.#<&>#g’

<t><h><i><s>< ><i><s>< ><a>< ><t><e><s><t>< ><l><i><n><e>

正则表达式 \w\+
匹配每一个单词,使用 <&>替换它,&
对应于之前所匹配到的单词

[root@oldboyedu43 oldboy]# echo this is a test line | sed ‘s#\w\+#<&>#g’

<this> <is> <a> <test> <line>

案例:echo “I am oldboy teacher.”
如果想保留这一行的单词oldboy

[root@oldboyedu43 oldboy]# echo "I am oldboy teacher." |sed -r ‘s#.*(ol.*y).*#\1#g’

oldboy

5.3.2 命令拼接——解决不会使用循环

将/oldboy/下所有.jpg的文件名修改为.avi

1. 先在屏幕上拼接出目标命令

[root@oldboyedu43 oldboy]# ls oldboy*.jpg |sed -r ‘s#(.*)jpg#mv & \1avi#g’

mv oldboy01.jpg oldboy01.avi

mv oldboy02.jpg oldboy02.avi

mv oldboy03.jpg oldboy03.avi

mv oldboy04.jpg oldboy04.avi

mv oldboy05.jpg oldboy05.avi

mv oldboy06.jpg oldboy06.avi

mv oldboy07.jpg oldboy07.avi

mv oldboy08.jpg oldboy08.avi

mv oldboy09.jpg oldboy09.avi

mv oldboy10.jpg oldboy10.avi

2. 最终交给 |bash执行

[root@oldboyedu43 oldboy]# ls oldboy*.jpg |sed -r ‘s#(.*)jpg#mv & \1avi#g’ |bash

[root@oldboyedu43 oldboy]# ls oldboy*

oldboy01.avi  oldboy03.avi  oldboy05.avi  oldboy07.avi  oldboy09.avi  oldboy.txt

oldboy02.avi  oldboy04.avi  oldboy06.avi  oldboy08.avi  oldboy10.avi

5.4 拓展

2.4.7 显示有规律的行

[root@zeq ~]# seq 10 |sed -n '1~2p'

1

3

5

7

9

5.4.1 rename替换(重命名)

rename     from
        to         file…

        你要替换的内容   替换成什么   替换哪些文件

rename      jpg
        avi        *.jpg

[root@oldboyedu43 oldboy]# rename jpg avi *.jpg

[root@oldboyedu43 oldboy]# ls

oldboy01.avi  oldboy03.avi  oldboy05.avi  oldboy07.avi  oldboy09.avi    

oldboy02.avi  oldboy04.avi  oldboy06.avi  oldboy08.avi  oldboy10.avi  

 5.4.2 sed里面表示非

2.5 sed命令中使用变量

root@zeq ~]# x=zeq               设置x变量为zeq

[root@zeq ~]# y=zeq1             设置y变量为zeq1

[root@zeq ~]# sed 's#$x#$y#g'  person.txt

101,zeq1,CEO

102,zhang,CTO

103,Love,COO

104,yy,CFO

105,faker,CIO

110,ahao,COCO

12306,xiao.UFO

5.4.3 特殊符号=获取行号

2.5.1 把文件person.txt文件中的每一行的内容 替换为对应的行号

for n in {1..7}                     这里使用的shell脚本中的for循环

do

     sed -i.bak "${n}s#.*#$n#g" person.txt

done

5.4.4 一条sed语句执行多条命令

2.5.2 批量重命名:删除文件名中的html_

touch zeq_html_{01..10}.jpg

方法1  命令行格式

[root@zeq data]# ls *.jpg|sed -r "s#(.*)(_.*)#mv & zeq\2#g"|bash

方法2  for循环

for i in {01..10}

do

mv zeq_${i}.jpg  zeq_html_${i}.jpg 

done

方法3  rename

rename  html_  ""    *.jpg        rename   修改谁    改为什么    修改什么文件

 

第6章 使用sed命令常见的坑

6.1 -r 与-i同时使用

  -r 参数在前面

-ri  正常

[root@oldboyedu43 oldboy]# cat ett.txt

oldboy

olldboooy

test

[root@oldboyedu43 oldboy]# sed -ri ‘s#[o]+{2}#AAAA#g’ ett.txt

[root@oldboyedu43 oldboy]# cat ett.txt

oldboy

olldbAAAAy

test

-ir  先把文件备份为xxr,然后再替换文件中的内容

[root@oldboyedu43 oldboy]# cat ett.txt

oldboy

olldboy                                                           源文件内容

test

[root@oldboyedu43 oldboy]# sed -ir ‘s#[l]+{2}#o#g’ ett.txt       sed -ir先备份 

[root@oldboyedu43 oldboy]# ll ett.*

-rw-r–r– 1 root root 20 Jan 12 19:58 ett.txt

-rw-r–r– 1 root root 20 Jan 12 19:56 ett.txtr                 备份为ett.txtr

[root@oldboyedu43 oldboy]# cat ett.txt                        因为在上面的命令里r已经不是参数,所以sed 默认不支持扩展正则,文件没有被修改,只是备份

oldboy                                                           

olldboy

test

[root@oldboyedu43 oldboy]# cat ett.txtr

oldboy

olldboy

test

[root@oldboyedu43 oldboy]# sed -rir ‘s#[l]+{2}#o#g’ ett.txt  重新给sed 加上 -r 参数,使 sed支持扩展正则

[root@oldboyedu43 oldboy]# ll ett.*                                    

-rw-r–r– 1 root root 19 Jan 12 19:58 ett.txt

-rw-r–r– 1 root root 20 Jan 12 19:58 ett.txtr                             新备份的文件覆盖了刚才的文件

[root@oldboyedu43 oldboy]# cat ett.txt                                     源文件被替换

oldboy

oodboy

test

[root@oldboyedu43 oldboy]# cat ett.txtr                                 备份文件内容不变

oldboy

olldboy

test

6.2 -i禁止与-n一起使用(回顾sed的执行过程)

 -i与-n一起使用会把源文件的内容清空

[root@oldboyedu43 oldboy]# cat ett.txtr

oldboy

olldboy

test

[root@oldboyedu43 oldboy]# sed -ni ‘s#oldboy#123456#g’ ett.txtr

[root@oldboyedu43 oldboy]# cat ett.txtr |wc -l

0