首页 > 代码库 > 三剑客之 sed详解

三剑客之 sed详解


 
 

 

sed

 

作者:Jack.X

归档:学习笔记

2017/4/13

 


                          三剑客之sed

第1章 sed详解:

1.1 sed介绍:

sedlinux命令中三剑客的老二sed命令是操作、过滤和转换文本内容的强大工具,常用功能有增删改查(增加,删除,修改,查询)。其中查询的功能中最常用的两大功能是过滤(过滤指定字符串),取行(取出指定行)。

我先在用的sed版本是GNU开源版本的,实验环境是Centos6.8系统,内核是2.6.32-642.el6.x86_64

[root@oldboyedu-35 ~]# cat /etc/redhat-release

CentOS release 6.8 (Final)

[root@oldboyedu-35 ~]# uname -r

2.6.32-642.el6.x86_64

[root@oldboyedu-35 ~]# sed --version

GNU sed version 4.2.1

Copyright (C) 2009 Free Software Foundation, Inc.

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

warranty; not even for MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE,

to the extent permitted by law.

1.2 语法格式:

sed  [options]  [sed - commands]  [input - file]

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

说明:

  1、注意sed软件以及后面选项、sed命令和输入文件,每个元素之间都至少有个空格。

  2、为了避免混淆,本文称呼sedsed软件sed - commandssed命令)是sed软件内置的一些命令选项,为了和前面的options(选项)区分,故称为sed命令。

  3sed - commands 既可以是单个sed命令,也可以搓个sed命令组合。

  4input - file(输入文件)是可选项,sed还能够从标准输入如管道获取输入。

1.3 命令执行流程:

概括流程:sed软件从文件或管道中读取一行,处理一行,输出一行;再读取一行,在处理一行,再输出一行……

小知识:一次一行的设计使得sed软件性能很高,sed在读取非常庞大的文件时不会出现卡顿的现象。用过vi命令就知道,用vi命令打开几十M或更大的文件,会发现有卡顿现象,这是因为vi命令打开文件时一次性将文件加载到内存,然后在打开,因此卡顿的时间长短就取决于从磁盘到内存的读取速度了。而且如果文件过大的话还会造成内存溢出现象。sed软件就很好的避免了这种情况,打开速度非常快,执行速度也很快。

技术分享

1.4 sed选项说明:

options(选项)

解释说明

-n

取消默认的sed权健的输出,鲳鱼sed命令的p连用。

-e

一行命令语句可以执行多条sed命令

-f

选项后面可以接sed脚本的文件名

-r

使用扩展正则表达式,默认情况sed只识别基本正则表达式。

-i

直接修改文件内容,而不是输出到终端。如果不使用-i选项sed软件只是修改在内存中的数据,并不会影响磁盘上的文件。

1.5 sed命令说明:

sed - commands

[sed命令]

解释说明

a

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

c

取代指定的行

d

删除指定的行

D

删除模式空间的部分内容,直到遇到换行\n结束操作,与多行模式相关。

i

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

h

把模式空间的内容复制到保持空间

H

把模式空间的内容追加到保持空间

g

把保持空间的内容复制到模式空间

G

把保持空间的内容追加到模式空间

x

交换模式空间和保持空间的内容

l

打印不可见的字符

n

情况模式空间的内容并读入下一行

N

不清空模式空间,并读取下一行数据并追加到模式空间

p

打印模式空间的内容,通常p会与选项-n一起使用

P

打印模式空间的内容,直到遇到换行符\n结束操作

q

退出sed

r

从指定文件读取数据

s

取代,s#oldboy#new#gè这里gs命令的替代标志,注意和g命令区分。

w

另存,把模式空间的内容保存到文件中

y

根据对应位置转换字符

label

定义一个标签

b  label

执行该标签后面的命令

t

如果前面的命令执行成功,那么就跳转到t指定的标签处,继续往下执行后续命令。否则,仍然继续正常的执行过程。

1.6 sed中常用特殊符号:

特殊符号

解释说明

对指定行以外的所有行应用命令

=

打印当前行行号

~

First~Step”表示从First行开始,以步长Step递增

&

代表被替换的内容

实现一行命令语句可以执行多条sed命令

{}

对单个 地址或地址范围执行批量操作

+

地址范围中用到的符号,做加法运算。

第2章 sed常见的四个功能

sed命令的"四斧头"--

2.1 增加:

第一把斧头è往文件指定位置追加或插入指定文本。

这个功能非常有用,比如我们平时往配置文件写入几行文本,最常用的是vivim命令,但是这个两个命令是交互式的命令,还需要我们在vivim编辑器几面输入字符串然后保存退出,操作有些繁琐但是还能用,但是当我们学会了shell脚本后,就会发现在脚本中不能正常使用vivim命令。

我们学习shell脚本主要是为了解放我们的双手,执行一个脚本,然后自动往文件中写入数据,不需要我们再动手,因此我们想到了sed软件,它能够帮助我们实现目的。

2.1.1 sed增加实例:

这里需要用到两个sed命令,分别是

a”:追加文本到指定行后,记忆方法:a的全拼是apend,意思是追加

i”:插入文本到指定行前,记忆方法:i的全拼是insert,意思是插入。

2.1.1.1单行增加:

  首先我们看一下单行增加的用法,说白了就是文件中增加一行文本,我们以前学过echo命令可以在文件的末尾追加文本,比较简单,但是我们还有其他的复杂需求,比如第10行插入一行数字等等,这里就需要sed出马了。比如下面的例子:

  创建环境:

[root@oldboyedu-35 ~]# cat>person.txt<<EOF

> 101,oldboy,CEO

> 102,zhangyao,CTO

> 103,Alex,COO

> 104,yy,CFO

> 105,feixue,CIO

> EOF

[root@oldboyedu-35 ~]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

一、追加:

[root@oldboyedu-35 ~]# sed ‘2a 106,dandan,CSO‘ person.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO

103,Alex,COO
104,yy,CFO
105,feixue,CIO

命令行详解:

  首先我们看一下命令的结果,我们可以看到在第二行"102zhangyaoCTO"后面追加了新的一行为"106dandanCSO"

二、插入:

[root@oldboyedu-35 ~]# sed ‘2i 106,dandan,CSO‘ person.txt
101,oldboy,CEO
106,dandan,CSO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

命令行详解:

  首先我们看一下命令的结果,我们可以看到在第二行"102zhangyaoCTO"前面插入了新的一行为"106dandanCSO"

2.1.1.2多行增加:

前面学习的内容已经实现了往文件追加或插入单行文本,但是还有插入多行文本的需求,我们也学过cat命令能够往文件中追加多行文本。

实例:

追加多行:

[root@oldboyedu-35 ~]# sed ‘2a 106,dandan,CSO\n107,sunxin,CEO‘ person.txt
101,oldboy,CEO
102,zhangyao,CTO
106,dandan,CSO
107,sunxin,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

  我们可以看到在第二行“102zhangyaoCTO”后面追加了两行106dandanCSO107sunxinCEO

插入多行:

[root@oldboyedu-35 ~]# sed ‘2i 106,dandan,CSO\n107,sunxin,CEO‘ person.txt
101,oldboy,CEO
106,dandan,CSO
107,sunxin,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

  可以看到第二行“102zhangyaoCTO”前面追加了两行“106dandanCSO107sunxinCEO”。

2.1.1.3企业案例:

sed命令在/etc/ssh/sshd_config的第13行前面插入下列五行:

Port 52113
PermitRootLogin no
PermitEmptyPasswords no
UseDNS no
GSSAPIAuthentication no

  【解答】:

[root@oldboyedu-35 ~]# sed ‘^C6,dandan,CSO\n107,sunxin,CEO‘ person.txt
[root@oldboyedu-35 ~]# sed ‘13i Port52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNSno\nGSSAPIAutheneicattion no‘ /etc/ssh/sshd_config |cat -n
    13  Port 52113
    14  PermitRootLogin no
    15  PermitEmptyPasswords no
    16  UseDNS no
    17  GSSAPIAutheneicattion no
    18  #Port 22

2.2 删除:

    这里我们要用到d这个sed命令。

2.2.1 删除单行:

[root@oldboyedu-35 ~]# sed ‘2d‘ person.txt
101,oldboy,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

第二行被删除。

注意:

    sed软件可以对单行或多行文本进行处理。如果在sed命令前面不知道地址范围,那么默认会匹配所有行。

[root@oldboyedu-35 ~]# sed ‘d‘ person.txt
[root@oldboyedu-35 ~]#

2.2.2 删除最后一行:

[root@oldboyedu-35 ~]# sed ‘$d‘ person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO

最后一行被删除。

2.2.3 删除多行:

[root@oldboyedu-35 ~]# sed ‘2,3d‘ person.txt
101,oldboy,CEO
104,yy,CFO
105,feixue,CIO

第二行和第三行被删除。

2.2.4 删除13行:

[root@oldboyedu-35 ~]# sed ‘1,+2d‘ person.txt
104,yy,CFO
105,feixue,CIO

第一行和第一行后面两行都被删除。

2.2.5 删除从二开始每次加两行(删除偶数行):

[root@oldboyedu-35 ~]# sed ‘2~2d‘ person.txt
101,oldboy,CEO
103,Alex,COO
105,feixue,CIO

偶数行被删除。

2.2.6 删除从一开始每次加两行(删除奇数):

[root@oldboyedu-35 ~]# sed ‘1~2d‘ person.txt
102,zhangyao,CTO
104,yy,CFO

奇数行被删除。

2.2.7 删除带有oldboy的行:

[root@oldboyedu-35 ~]# sed ‘/oldboy/d‘ person.txt
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

或者:

[root@oldboyedu-35 ~]# sed ‘/ol.*/d‘ person.txt
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

带有oldboy字符的行被删除。

2.2.8 删除排除某个行或多行(取反):

[root@oldboyedu-35 ~]# sed ‘2~2!d‘ person.txt
102,zhangyao,CTO
104,yy,CFO

[root@oldboyedu-35 ~]# sed ‘2!d‘ person.txt
102,zhangyao,CTO

!带有取反的意思,如例子:除了偶数行其他全删了和除了第二行其他全被删。

2.2.9 删除不规则的跳行:

[root@oldboyedu-35 ~]# sed ‘1d;2d;4d‘ person.txt
103,Alex,COO
105,feixue,CIO

或者

[root@oldboyedu-35 ~]# sed -e ‘1d‘ -e ‘3d‘ -e ‘5d‘person.txt
102,zhangyao,CTO
104,yy,CFO

一些不规则的跳行被删除。

2.2.10 地址范围的含义:

地址范围

含义

10{sed  - commands}

对第10行操作

10,20{sed  - commands}

1020行操作,包括第10,20

10,20+{sed  - commands}

1030{10+20}行操作,包括第10,30

1~2{sed  - commands}

1,3,5,7…..操作

10,$  {sed - commands}

10到最后一行($代表最后一行)操作,包括第10

/oldboy/{sed  -commands}

对匹配oldboy的行操作

/oldboy/,/Alex/{sed  - commands}

对匹配oldboy的行到匹配Alex的行操作

/oldboy/,${sed  -commands}

对匹配oldboy的行到最后一行操作

/oldboy/,10{sed  - command}

对匹配oldboy的行到第10行操作,注意:如果前10行没有匹配到oldboysed软件会显示10行以后的匹配oldboy的行。

1/Alex/{sed - commands}

对第一行到匹配Alex的行操作

/oldboy/,+2{sed  - commands}

对匹配oldboy的行到行的气候的2行操作。

企业案例2:打印文件内容但不包括oldboy

  这是一道企业的面试题,很简单,就是把包含oldboy字符串的行删掉即可,我们可以用“grep -v”取反得到我们想要的结果,但在这里我们使用的sed软件可以实现。

  【解答】:

[root@oldboyedu-35 ~]# sed ‘/oldboy/d‘ person.txt 
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

  学完sed软件两把斧头,都是锋利的斧头!当然后面还有更厉害的大招è改,这是一个杀招,杀手锏,一出手就定乾坤。在学习linux时,我们最常见的操作就改配置文件,改参数等等,而且更秒的是前面我们学习过的增加和删除其实都可以用我们准备要学的修改变相实现。

2.3 修改:

2.3.1 换行替换:

这里用到的sed的命令是c:用新行取代旧行,记忆方法:c的全拼是change,意思是替换。

 【例子】:

[root@oldboyedu-35 ~]# cat person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO
[root@oldboyedu-35 ~]# sed ‘2c 007,sunxin,CEO‘person.txt
101,oldboy,CEO
007,sunxin,CEO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

2.3.2 文本替换:

  接下来说的这个功能,有工作经验的同学应该非常得熟悉,因为使用sed软件80%的场景就是使用替换功能。

  这里用到的sed命令、选项:

s”单独使用è将每一行中第一处匹配的字符串进行替换。èsed命令

g”每一行进行全部替换èsed命令s的替换标志之一(全局替换)èsed命令。

-i”修改文件内容èsed软件的选项(参数),不是sed命令i

sed软件替换模型($表示被替换成%

sed  -i  ‘s/$/%/g‘ oldboy.log

sed  -i  ‘s#$#%#g‘ oldboy.log

注意:

  s#$#%#g ,$能用正则表达式 ,但%不能用,必须是具体的。因为%使用正则的话会让sed软件无所适从,它不知道你要替换什么内容。

  默认sed软件是对默认空间(内存中的数据)操作,而-i选项会更改磁盘上的文件内容。

2.3.3 企业案例:指定行修改配置文件

    前面我们学过的模型能后将文件中所有满足条件的文本进行操作,但是我们也会碰到指定行精确修改配置文件的需求,因为这样可以避免修改多了地方。

[root@oldboyedu-35 ~]# sed ‘3s#0#9#g‘ person.txt
101,oldboy,CEO
102,zhangyao,CTO
193,Alex,COO
104,yy,CFO
105,feixue,CIO

  命令说明,前面学习的例子在sed命令“s”前没有指定地址范围,因此默认是对所有行进行操作。

  而这个案列要求值将第3行的0换成9,这里就用到了我们前面学过的地址范围只是,在sed命令“s”前加上3就代表对第三行进行替换

 

 

2.3.4 特别注意:

一、

  sed‘s#oldboy#$LANG#g‘ person.txt $LANG并不能解析出来

[root@oldboyedu-35 ~]# sed ‘s#oldboy#$LANG#g‘person.txt
101,$LANG,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

  说明:如果使用单引号我们可以看见结果是替换失败,因为我们知道单引号的作用是所见即所得,因此这里的oldboy并不会解析成$LANG

二、

sed ‘s#oldboy#‘$LANG‘#g‘ person.txt 第一个单引号和第二个单引号才是一组。所以这条可以执行出$LANG可以执行出来。

[root@oldboyedu-35 ~]# sed ‘s#oldboy#‘$LANG‘#g‘person.txt
101,en_US.UTF-8,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

  说明:表面看起来结果是$LANG是解析不出来的,但其实这是用了障眼法,在我们眼中分段‘$LANG‘是解析不出来的,因为单引号是所见即所得。但是并非如此,真正的分段是‘s#oldboy#‘  ‘#g‘ 说以$LANG已经被解析了和上面的不一样了。

2.3.5 分组替换\(\)\1的使用说明:

  sed软件的\(\)的功能可以记住正则表达式的一部分,其中,\1位第一个记住的模式即第一个小括号中的匹配内容,\2第二记住的模式,即第二个小括号中的匹配内容,sed最多可以记住9个。

例:echo "I am oldboy teacher" 如果想保留着一行的单词oldboy,删除剩下的部分,使用圆括号标记想保留的部分。

[root@oldboyedu-35 ~]# echo "I am oldboyteacher" |sed -r ‘s#.*(oldboy).*#\1#g‘
oldboy

[root@oldboyedu-35 ~]# echo "I am oldboyteacher" |sed -r ‘s#.*am ([a-z].*) te.*#\1#g‘
oldboy

[root@oldboyedu-35 ~]# echo "I am oldboyteacher" |sed -r ‘s#(.*am) ([a-z].*) (te.*)#\2#g‘
oldboy

[root@oldboyedu-35 ~]# echo "I am oldboyteacher" |sed  ‘s#.*\(oldboy\).*#\1#g‘
oldboy
[root@oldboyedu-35 ~]# echo "I am oldboy teacher" |sed  ‘s#\(.*am\) \([a-z].*\) \(te.*\)#\2#g‘
oldboy
[root@oldboyedu-35 ~]# echo "I am oldboy teacher" |sed  ‘s#.*am \([a-z].*\) te.*#\1#g‘
oldboy

技术分享

  说明:()是扩展正则表达式的元字符,sed软件默认识别基本正则表达式,想要使用扩展正则表达式需要使用\转义,即\\),sed使用-r 选项则可以识别扩展正则表达式,此时使用\\)反而会出错。

  2种格式总结:

sed  ‘s#\.*\#\1#g‘

sed -r ‘s#.*#\1#g‘

命令说明:固定搭配,弄反了就错了,不使用-r选项就需要使用转义符号\,使用-r选项就可以直接使用(),推荐使用这种方法。

练习题:请执行命令取出linuxeth0IP地址。

[root@oldboyedu-35 ~]# ifconfig eth0
eth0      Linkencap:Ethernet  HWaddr00:0C:29:99:16:68 
          inetaddr:192.168.56.128 Bcast:192.168.56.255 Mask:255.255.255.0
          inet6addr: fe80::20c:29ff:fe99:1668/64 Scope:Link
          UPBROADCAST RUNNING MULTICAST MTU:1500  Metric:1
          RXpackets:17333 errors:0 dropped:0 overruns:0 frame:0
          TXpackets:11501 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RXbytes:1714097 (1.6 MiB)  TX bytes:1378349(1.3 MiB)

[root@oldboyedu-35 ~]# ifconfig eth0 |sed -nr‘2s#^(.*)dr:(.*)Bc(.*)$#\2#gp‘
192.168.56.128 
[root@oldboyedu-35 ~]# ifconfig eth0 |sed -nr‘2s#^.*ddr:(.*)Bca.*$#\1#gp‘
192.168.56.128 

2.3.6 企业案例:系统开机启动项优化

  【解答】:

第一步: 查看

[root@oldboyedu-35 ~]# chkconfig --list |grep"3:on" |egrep -v "sshd|crond|neuwork|rsylog|sysstat"

abrt-ccpp      0:off      1:off      2:on       3:on       4:on       5:on       6:off

abrtd                0:off      1:off      2:on       3:on       4:on       5:on       6:off

acpid               0:off      1:off      2:on       3:on       4:on       5:on       6:off

atd                 0:off      1:off      2:on       3:on       4:on       5:on       6:off

auditd               0:off      1:off      2:on       3:on       4:on       5:on       6:off

blk-availability    0:off      1:on       2:on       3:on       4:on       5:on       6:off

第二步:筛选3级别开启,并排除一些服务

[root@oldboyedu-35 ~]# chkconfig --list |grep"3:on" |egrep -v "sshd|crond|neuwork|rsyslog|sysstat" 
abrt-ccpp       0:off      1:off      2:on       3:on       4:on       5:on       6:off
abrtd                 0:off      1:off      2:on       3:on       4:on       5:on       6:off
acpid                0:off      1:off      2:on       3:on       4:on       5:on       6:off
atd                  0:off      1:off      2:on       3:on       4:on       5:on       6:off
auditd                0:off      1:off      2:on       3:on       4:on       5:on       6:off
blk-availability    0:off      1:on       2:on       3:on       4:on       5:on       6:off
cpuspeed             0:off      1:on       2:on       3:on       4:on       5:on       6:off
haldaemon            0:off      1:off      2:on       3:on       4:on       5:on       6:off

第三步:取出服务名

[root@oldboyedu-35 ~]# chkconfig --list |grep"3:on" |egrep -v "sshd|crond|neuwork|rsyslog|sysstat" |awk‘{print $1}‘ 
abrt-ccpp
abrtd
acpid
atd
auditd
blk-availability
cpuspeed
haldaemon
ip6tables
iptables

第四步:用sed完成拼接

[root@oldboyedu-35 ~]# chkconfig --list |grep"3:on" |egrep -v "sshd|crond|neuwork|rsyslog|sysstat" |awk‘{print $1}‘  |sed ‘s#\(.*\)#chkconfig \1off#g‘
chkconfig abrt-ccpp off
chkconfig abrtd off
chkconfig acpid off
chkconfig atd off
chkconfig auditd off
chkconfig blk-availability off
chkconfig cpuspeed off
chkconfig haldaemon off
chkconfig ip6tables off
chkconfig iptables off
chkconfig irqbalance off
chkconfig kdump off
chkconfig lvm2-monitor off
chkconfig mdmonitor off
chkconfig messagebus off
chkconfig netconsole off
chkconfig netfs off
chkconfig network off

第五步:执行并检查

[root@oldboyedu-35 ~]# chkconfig --list |grep"3:on" |egrep -v "sshd|crond|neuwork|rsyslog|sysstat" |awk‘{print $1}‘  |sed ‘s#\(.*\)#chkconfig \1off#g‘ |bash
[root@oldboyedu-35 ~]# chkconfig --list
abrt-ccpp       0:off      1:off      2:off      3:off      4:off      5:off      6:off
abrtd                 0:off      1:off      2:off      3:off      4:off      5:off      6:off
acpid                0:off      1:off      2:off      3:off      4:off      5:off      6:off
atd                  0:off      1:off      2:off      3:off      4:off      5:off      6:off
auditd                0:off      1:off      2:off      3:off      4:off      5:off      6:off
blk-availability    0:off      1:on       2:off      3:off      4:off      5:off      6:off
cpuspeed             0:off      1:on       2:off      3:off      4:off      5:off      6:off
crond                0:off      1:off      2:on       3:on       4:on       5:on       6:off
haldaemon            0:off      1:off      2:off      3:off      4:off      5:off      6:off
ip6tables        0:off      1:off      2:off      3:off      4:off      5:off      6:off
iptables         0:off      1:off      2:off      3:off      4:off      5:off      6:off
irqbalance       0:off      1:off      2:off      3:off      4:off      5:off      6:off
kdump              0:off      1:off      2:off      3:off      4:off      5:off      6:off
lvm2-monitor    0:off      1:on       2:off      3:off      4:off      5:off      6:off
mdmonitor           0:off      1:off      2:off      3:off      4:off      5:off      6:off

2.3.7 特殊符号&代表被替换的内容:

  这是一个特殊技巧,在适合的场景使用特别方便,下面用特殊符号“&”与分组替换一起使用,进行对比。

[root@oldboyedu-35 ~]# sed -r‘s#(.*),(.*),(.*)#&------\1 \2 \3#g‘ person.txt
101,oldboy,CEO------101 oldboy CEO
102,zhangyao,CTO------102 zhangyao CTO
103,Alex,COO------103 Alex COO
104,yy,CFO------104 yy CFO
105,feixue,CIO------105 feixue CIO

命令说明:

1、这里将分组替换和&符号放在一起对比

2、命令中的分组天幻使用了3个小括号,每个小括号分别代表每一行以逗号作为分隔符的每一刻。

3、上面命令的&符号代表每一行,即模型中‘s#@#%#g‘中的%

2.3.8 企业案例5:批量重命名文件

当前目录下有文件如下所示:

[root@oldboyedu-35 test]# touchstu_102999_{1..5}_finished.jpg
[root@oldboyedu-35 test]# ll
total 0
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_1_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_2_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_3_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_4_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_5_finished.jpg

  要求用sed命令重命名,效果为

stu_102999_1_finishedjpg == > stu_102999_1.jpg 即删除文件名的_finished

  【解答】:

[root@oldboyedu-35 test]# find . -type f -name"*.jpg"|sed -r ‘s#(.*)_f.*ed(.*)#mv & \1 \2#g‘
mv ./stu_102999_3_finished.jpg ./stu_102999_3 .jpg
mv ./stu_102999_1_finished.jpg ./stu_102999_1 .jpg
mv ./stu_102999_4_finished.jpg ./stu_102999_4 .jpg
mv ./stu_102999_2_finished.jpg ./stu_102999_2 .jpg
mv ./stu_102999_5_finished.jpg ./stu_102999_5 .jpg

2.3.9 rename改名工具:

[root@oldboyedu-35 test]# ll
total 0
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_1_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_2_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_3_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_4_finished.jpg
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_102999_5_finished.jpg

[root@oldboyedu-35 test]#rename jpg JPG *
[root@oldboyedu-35 test]#ll
total 0
-rw-r--r-- 1 root root 0Apr 14 15:38 stu_102999_1_finished.JPG
-rw-r--r-- 1 root root 0Apr 14 15:38 stu_102999_2_finished.JPG
-rw-r--r-- 1 root root 0Apr 14 15:38 stu_102999_3_finished.JPG
-rw-r--r-- 1 root root 0Apr 14 15:38 stu_102999_4_finished.JPG
-rw-r--r-- 1 root root 0Apr 14 15:38 stu_102999_5_finished.JPG

 注意:一次只能修改一次

   例如:

[root@oldboyedu-35 test]# rename 1 0 *
[root@oldboyedu-35 test]# ll
total 0
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_1_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_2_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_3_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_4_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_5_finished.JPG
[root@oldboyedu-35 test]# rename 1 0 *
[root@oldboyedu-35 test]# ll
total 0
-rw-r--r-- 1 root root 0 Apr 14 15:38 stu_002999_0_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38stu_002999_2_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38stu_002999_3_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38stu_002999_4_finished.JPG
-rw-r--r-- 1 root root 0 Apr 14 15:38stu_002999_5_finished.JPG

2.4 查看:

  说的这里,可以稍微踹口气了。因为sed里最常用最重要的我们已经学完了,接下来轻松解说一下sed的最后一把斧头:查看文本

  这个功能也是非常得用,比如我们想查看文件中的某些行,以前最常用的是catmoreless命令等,但这些命令有些缺点,就是不能查看指定的行,而我们用了很久的sed命令就有这个功能了,而且我们前面也说过使用sed比其他命令的读取速度更快。

  这里我们需要用到1sed命令

  p”:输出指定内容,但默认会输出2次匹配的结果,因此使用-n选项取消默认输出,记忆方法:p的全拼是print,意思是打印。

2.4.1 按行查询:

[root@chensiqi1 ~]# sed ‘2p‘ person.txt

101,chensiqi,CEO

102,zhangyang,CTO

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@chensiqi1 ~]# sed -n ‘2p‘ person.txt

102,zhangyang,CTO

 

命令说明:选项-n取消默认输出,只输出匹配的文本,大家只需要记住使用命令p必用选项-n

 

[root@chensiqi1 ~]# sed -n ‘2,3p‘ person.txt

102,zhangyang,CTO

103,Alex,COO

命令说明:查看文件的第2行到3行,使用地址范围“23”。取行就用sed,最简单

[root@chensiqi1 ~]# sed -n ‘1~2p‘ person.txt

101,chensiqi,CEO

103,Alex,COO

105,feixue,CIO

命令说明:打印文件的135行。~代表步长

[root@chensiqi1 ~]# sed -n ‘p‘ person.txt

101,chensiqi,CEO

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

 

命令说明:不指定地址范围,默认打印全部内容。

2.4.2 按字符串查询:

[root@chensiqi1 ~]# sed -n ‘/CTO/p‘ person.txt

102,zhangyang,CTO

命令说明:打印含CTO的行

[root@chensiqi1 ~]# sed -n ‘/CTO/,/CFO/p‘person.txt

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

命令说明:打印含CTO的行到含CFO的行。

2.4.3 混合查询:

[root@chensiqi1 ~]# sed -n ‘2,/CFO/p‘ person.txt

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

命令说明:打印第2行到含CFO的行。

[root@chensiqi1 ~]# sed -n ‘/feixue/,2p‘person.txt

105,feixue,CIO

命令说明:特殊情况,前两行没有匹配到feixue,就向后匹配,如果匹配到feixue就打印此行。所以这种混合地址不推荐使用。

2.4.4 过滤多个字符:

[root@chensiqi1 ~]# sed -rn ‘/chensiqi|yy/p‘person.txt

101,chensiqi,CEO

104,yy,CFO

命令说明:

    使用扩展正则“|”,为了不使用转义符号“\”,因此使用-r选项开启扩展正则表达式模式

第3章 sed命令应用知识扩展:

3.1 sed修改文件的同时进行备份

[root@chensiqi1 ~]# cat person.txt

101,chensiqi,CEO

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@chensiqi1 ~]# sed -i.bak ‘s#zhangyang#NB#g‘person.txt

[root@chensiqi1 ~]# cat person.txt

101,chensiqi,CEO

102,NB,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@chensiqi1 ~]# cat person.txt.bak

101,chensiqi,CEO

102,zhangyang,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

命令行说明:

    -i参数的后边加上.bak.任意字符),sed会对文件进行先备份后修改

3.2 特殊符号:

[root@chensiqi1 ~]# sed ‘=‘ person.txt

1

101,chensiqi,CEO

2

102,NB,CTO

3

103,Alex,COO

4

104,yy,CFO

5

105,feixue,CIO

命令说明:使用特殊符号“=”就可以获取文件的行号,这是特殊用法,记住即可。从上面的命令结果我们也发现了一个不好的地方:行号和行不在一行。

[root@chensiqi1 ~]# sed ‘1,3=‘ person.txt

1

101,chensiqi,CEO

2

102,NB,CTO

3

103,Alex,COO

104,yy,CFO

105,feixue,CIO

命令说明:只打印123行的行号,同时打印输出文件中的内容

[root@chensiqi1 ~]# sed ‘/yy/=‘ person.txt

101,chensiqi,CEO

102,NB,CTO

103,Alex,COO

4

104,yy,CFO

105,feixue,CIO

命令说明:

    只打印正则匹配行的行号,同时输出文件中的内容

[root@chensiqi1 ~]# sed -n ‘/yy/=‘ person.txt

4

 

命令说明:只显示行号但不显示行的内容即取消默认输出。

[root@chensiqi1 ~]# sed -n ‘$=‘ person.txt

5

命令说明:

    $”代表最后一行,因此显示最后一行的行号,变相得出文件的总行数。

方法改进:

[root@chensiqi1 ~]# sed ‘=‘ person.txt | sed‘N;s#\n# #‘

1 101,chensiqi,CEO

2 102,NB,CTO

3 103,Alex,COO

4 104,yy,CFO

5 105,feixue,CIO

命令说明:前面sed获取文件的行号有一个缺点,我们这里使用Sed命令N来补偿这个缺点。Sed命令N读取下一行数据并附加到模式空间。

3.3 特殊符号{}的使用

[root@chensiqi1 ~]# sed -n ‘2,4p;=‘ person.txt

1

102,NB,CTO

2

103,Alex,COO

3

104,yy,CFO

4

5

命令说明:-n去掉默认输出,2,4p,输出24行内容,=输出全部的行的行号

[root@chensiqi1 ~]# sed -n ‘2,4{p;=}‘ person.txt

102,NB,CTO

2

103,Alex,COO

3

104,yy,CFO

4

命令说明:

    24{p;=}’代表统一输出24行的行号和内容

3.4 sed如何取不连续的行:

[root@chensiqi1 ~]# sed -n ‘1p;3p;5p‘ person.txt

101,chensiqi,CEO

103,Alex,COO

105,feixue,CIO

3.5 Ms# # #NG的使用:

语法说明:

  • MSè对第M行处理,无g替换标志,只处理第一处匹配,有g天幻标志则对第M行全部替换

  • Ngè对每一行,从第N处开始替换

  • MsNg合用表示只对第M行从第N处匹配开始替换

案例演示:

使用下面的命令语句创建新的测试文本,通过下面的矩阵我们可以很清晰的看到替换的结果。

cat >num.txt <<EOF

1 1 1 1 1

1 1 1 1 1

1 1 1 1 1

1 1 1 1 1

EOF

[root@oldboyedu-35 ~]# sed ‘2s#1#0#2g‘ num.txt 
1 1 1 1 1
1 0 0 0 0
1 1 1 1 1
1 1 1 1 1
[root@oldboyedu-35 ~]# sed ‘2s#1#0#g‘ num.txt 
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
1 1 1 1 1
[root@oldboyedu-35 ~]# sed ‘2s#1#0#2‘ num.txt 
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1
1 1 1 1 1
[root@oldboyedu-35 ~]# sed ‘2s#1#0#2‘ num.txt 

 

第4章 sed模式空间与保持空间:

SED之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“暂存缓冲区(holdingspace)这2个空间的使用。

sed编辑器逐行处理文件,并将输出结果打印到屏幕上。sed命令将当前处理的行读入模式空间(pattern space)进行处理,sed在该行上执行完所有命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间中删除,然后将下一行读入模式空间,进行处理、显示。处理完文件的最后一行,sed便结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明-i选项。

sed之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“保持空间(hold space)这2个空间的使用。

 

模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理,用于处理文本行。

保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域,用于保留文本行,是保存已经处理过的输入行,默认有一个空行。

技术分享

4.1 模式空间的操作命令:

4.1.1 命令n

命令n的作用:情况当前模式空间的内容,然后从输入文件中读取下一行。

命令n的作用执行过程中遇到n,那么它会改变正常的执行流程(读取数据-执行命令-打印输出-重复循环)。

假定命令n前后各有两个其他命令

sed -command -1

sed -command -2

n

sed -command -3

sed -command -4

 

这种情况下,sed -conroand-1sed -conroand-2会在模式空间中执行,然后把内容输出到屏暮,遇到n就会清空当前模式空间的内容sed -co sed -conrnand-4应用于新的模式空间的内容。

详情看下面例子:

[root6oldboyedu-35 ]# sed -n’p:p:n:p:p’ person, txt

101,  sunxin, CEO

101,       sunxin,CEO

102,       zhangyao,CTO

102,       zhangyao,CTO

103,       Alex,COO

103,       Alex,COO

104,       yy,CFO

104,       yy,CFO

105,       feixue,CIO 105, feixue, CIO

_root6oldboyedu-35 ]# sedsed-d -n —hide=H0LD ’p:p:n:p:p’ person, txt

PATT: 101, sunxin, CEOS

COMMp

101, sunxin, CEO PATT: 101, hujing, CEOS

PATT : 101.sunxin.CEO$

COMMp

101,       sunxin,CEO PATT: 101, hujing, CEOS COMMp

101,       sunxin,CEO PATT: 101, hujing, CEOS COMMn

PATT:102, zhangyao, CTO$

COMMp

102,       zhangyao,CTO PATT:102, zhangyao, CTO$

COMMp

102,       zhangyao,CTO PATT:102, zhangyao, CTO$

PATT:103, Alex, COO$

COMMp

103,       Alex,COO PATT:103, Alex, COO$

COMMp

103,       Alex,COO PATT:103, Alex, COO$

COMMn

PATT:104, yy,CFO$

COMMp

104,       yy,CFO PATT:104, yyCFOS

PATT :104.yy.CEO$

4.1.2 命令N

 

N

不清空模式空间,并读取下一行数据追加到模式空间

   如果在命令执行过程中遇到N,那么它会改变正常的执行流程(读取数据-执行命令-打印输出-重复循环)

假定命令n前后咅有两个其他命令

sed -command-1

N

sed -command-2

这种情况下,sed -command-1会在模式空间中执行,然后把内容输出到屏暮,遇到N就会不清空当前模式空间的内容(sed -command-1执行当前行的内容)并读取下一行内容追加到模式空间中,然后把sed -command-2应用于新的模 式空间的内容。

技术分享

详情请看下列例子  

[rootoldboyedu—35 ]# sed _n’p:N:p’ person, txt

101, sunxin, CEO

101,       sunxin,CEO

102,       zhangyao,CTO

103,       Alex,COO

103,       Alex,COO

104.       yy.CFO

4.2 sed测试工具sedsed

sedsed软件是一个很椁的调试sed语句的工具,sedsed软件会详细的显示sed执行流程

sedsed软件是时下最流行的语言python写的,简单易用

sedsed软件最新版本是1.0版本,这个版本支持所有安装python2版本的系统平台 4.1安装sedsed软件

下载sedsed软件 

wget http//sedsed. sourceforge. net/sedsed-1. 0  -0 /bin/sedsed

给文件加上可执行权限

chmod +x /bin/sedsed

快速安装命令    

wget http//sedsed. sourceforge. net/sedsed-1. 0 -0 /bin/sedsed

chmod +x /bin/sedsed

4.2.1 sedsed语法与选项

    sedsed软件可以非常清晰的告诉我们sed软件执行的流程,接下来介绍一下sedsed的语法,sedsed取代sed取代软件的位置,下面是sedsed命令的常用选项

选项

解释说明

-d

开启调试模式

--hids

隐藏一下调试信息,选项有PATTHOLDCOMM

PATTpattem模式的缩写,即模式空间

HOLD是保持空间

COMMcommand的缩写,即sed命令

-n

取消默认输入

$

表示文件的结尾,如果在文件的开头是$,则表示空行

 

4.2.2 sedsed软件执行过程

  sedsed软件通过一些选项来讲sedsed名每一次操作都记录下来输出到屏幕,当sed命令不够直观的时候,就可以用sedsed软件来分析sed团建是如何取执行的,非常直观和简单

 sedsed固定使用格式sedsed -d-n --hids=HOLD ‘[sed - commands]‘ [input - file]

当只有一个命令时

[root@oldboyedu-35 ~]# sed -n ‘p‘ person.txt
101,oldboy,CEO
102,zhangyao,CTO
103,Alex,COO
104,yy,CFO
105,feixue,CIO

[root@oldboyedu-35 ~]# sedsed -d -n --hide=HOLD‘p‘ person.txt
PATT:101,oldboy,CEO$
COMM:p
101,oldboy,CEO
PATT:101,oldboy,CEO$
PATT:102,zhangyao,CTO$
COMM:p
102,zhangyao,CTO
PATT:102,zhangyao,CTO$
PATT:103,Alex,COO$
COMM:p
103,Alex,COO
PATT:103,Alex,COO$
PATT:104,yy,CFO$
COMM:p
104,yy,CFO
PATT:104,yy,CFO$
PATT:105,feixue,CIO$
COMM:p
105,feixue,CIO
PATT:105,feixue,CIO$

sedsed软件可以将所有sed软件执行流程反馈出来

   当有多个sed命令时

[root@oldboyedu-35 ~]# sed -n ‘p;n‘ person.txt
101,oldboy,CEO
103,Alex,COO
105,feixue,CIO

[root@oldboyedu-35 ~]# sedsed -d -n --hide=HOLD‘p;n‘ person.txt
PATT:101,oldboy,CEO$
COMM:p
101,oldboy,CEO
PATT:101,oldboy,CEO$
COMM:n
PATT:102,zhangyao,CTO$
PATT:103,Alex,COO$
COMM:p
103,Alex,COO
PATT:103,Alex,COO$
COMM:n
PATT:104,yy,CFO$
PATT:105,feixue,CIO$
COMM:p
105,feixue,CIO
PATT:105,feixue,CIO$
COMM:n

 

 

 

                                          


本文出自 “Jack.X” 博客,请务必保留此出处http://jackx.blog.51cto.com/12670250/1917136

三剑客之 sed详解