sed文本处理工具

 

    本章内容

Ø  sed介绍

Ø  sed用法

Ø  sed高级用法

 

1sed介绍

Stream EDitor, 行编辑器

       sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

       功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等

2sed工具

2.1、用法

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

2.2、常用选项

       -n不输出模式空间内容到屏幕,即不自动打印

       -e: 多点编辑

       -f/ PATH/SCRIPT_FILE : 从指定文件中读取编辑脚本

       -r: 支持使用扩展正则表达式

       -i.bak: 备份文件并原处编辑

2.3script

       ‘地址命令’ 对指定行号处理,默认不指定,处理所有行

2.3.1、地址定界

       (1) 不给地址对全文进行处理

       (2) 单地址:

              #: 指定的行$最后一行

              /pattern/被此处模式所能够匹配到的每一行(支持正则表达式)

       (3) 地址范围:

              #,#         例:10,20

              #,+#

              /pat1/,/pat2/模式之间处理,用逗号隔开     #开始执行pat1模式匹配到pat2模式行结果包含中间行

              #,/pat1/  行号加模式混用   例:从指定行号开始处理,直到模式匹配结束

       (4) ~:步进

              1~2 奇数行

              2~2 偶数行

2.3.2、编辑命令

       d: 删除模式空间匹配的行,并立即启用下一轮循环

       p打印当前模式空间内容,追加到默认输出之后

       a [\]text在指定行后面追加文本

                            支持使用\n实现多行追加

       i [\]text在行前面插入文本

       c [\]text替换行为单行或多行文本

       w /path/somefile: 保存模式匹配的行至指定文件

       r /path/somefile读取指定文件的文本至模式空间中,匹配到的行后

       =: 为模式空间中的行打印行号

       !模式空间中匹配行取反处理

例子:

[root@centos7 ~]#seq 1 10|sed '2p'             #打印第2

1

2

2

3

4

5

6

7

8

9

10

[root@centos7 ~]#seq 1 10|sed -n '2p'                       #-n关闭自动打印

2

[root@centos7 ~]#sed -n '/root/p' /etc/passwd          #打印包含root的行

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

[root@centos7 ~]#sed -n '$p' /etc/passwd          #打印最后一行

rick:x:1000:1000:rick:/home/rick:/bin/bash

[root@centos7 ~]#sed -n '/^root/p' /etc/passwd        #root开头打印

root:x:0:0:root:/root:/bin/bash

[root@centos7 ~]#sed -n '2,5p' /etc/passwd       #打印指定行号

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@centos7 ~]#sed -n '2,+3p' /etc/passwd            #指定行,n+1

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@centos7 ~]#sed -n '/^b/,/^f/p' /etc/passwd       #多模式匹配处理

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

adm:x:3:4:adm:/var/adm:/sbin/nologin

lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sync:x:5:0:sync:/sbin:/bin/sync

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

halt:x:7:0:halt:/sbin:/sbin/halt

mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

games:x:12:100:games:/usr/games:/sbin/nologin

ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

[root@centos7 ~]#seq 1 10|sed -n '1~2p'            #打印奇数行

1

3

5

7

9

[root@centos7 ~]#seq 1 10|sed -n '2~2p'            #打印偶数行

2

4

6

8

10

[root@centos7 ~]#seq 1 10|sed -n -e '2p' -e '6p'    #多点编辑

2

6

[root@centos7 ~]#cat sedscript.txt             #创建sedscript

2~2p

[root@centos7 ~]#seq 1 10|sed -n -f sedscript.txt   #指定sedscript脚本处理编辑

2

4

6

8

10

[root@centos7 ~]#seq 1 10|sed '2d'             #删除第2

1

3

4

5

6

7

8

9

10

[root@centos7 ~]#seq 1 10|sed '2!d'            #取反;不包括第2行删除

2

[root@centos7 ~]#sed -n '/root/=' /etc/passwd          #匹配模式中字符串以行号显示

1

10

[root@centos7 ~]#seq 1 10|sed '2,5a===='         #指定行后追加内容

1

2

====

3

====

4

====

5

====

6

7

8

9

10

[root@centos7 ~]#sed '/aliases/aalias p=poweroff' .bashrc          #aliases后追加一个别名参数

# .bashrc

 

# User specific aliases and functions

alias p=poweroff

 

alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

 

# Source global definitions

if [ -f /etc/bashrc ]; then

        . /etc/bashrc

fi

[root@centos7 ~]#sed -i.bak '/aliases/aalias p=poweroff' .bashrc      #先备份,再执行追加内容;实时修改原文件

[root@centos7 ~]#cat .bashrc        #查看原文件变化

# .bashrc

 

# User specific aliases and functions

alias p=poweroff               #追加内容

 

alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

 

# Source global definitions

if [ -f /etc/bashrc ]; then

        . /etc/bashrc

fi

[root@centos7 ~]#cat .bashrc.bak              #备份OK

# .bashrc

 

# User specific aliases and functions

 

alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

 

# Source global definitions

if [ -f /etc/bashrc ]; then

        . /etc/bashrc

fi

使用sed工具追加别名到配置文件

[root@centos7 ~]#sed -i.bak2 '/aliases/aalias cdnet="cd /etc/sysconfig/network-scripts/"' .bashrc

#先备份,再追加到配置文件

[root@centos7 ~]#cat .bashrc        #查看原文件追加别名

# .bashrc

 

# User specific aliases and functions

alias cdnet="cd /etc/sysconfig/network-scripts/"

alias p=poweroff

 

alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

 

# Source global definitions

if [ -f /etc/bashrc ]; then

        . /etc/bashrc

fi

[root@centos7 ~]#. .bashrc            #执行配置文件

[root@centos7 ~]#cdnet         #测试别名

[root@centos7 /etc/sysconfig/network-scripts]#            #执行别名OK

[root@centos7 /etc/sysconfig/network-scripts]#alias             #查找别名列表

alias cdnet='cd /etc/sysconfig/network-scripts/'

alias cp='cp -i'

alias egrep='egrep --color=auto'

alias fgrep='fgrep --color=auto'

alias grep='grep --color=auto'

alias l.='ls -d .* --color=auto'

alias ll='ls -l --color=auto'

alias ls='ls --color=auto'

alias mv='mv -i'

alias p='poweroff'

alias rm='rm -i'

alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

使用-a追加内容,若内容前面添加空格需要加“\

[root@centos7 ~]#seq 1 10|sed '2,5a   ===='     #追加字符串前加空格

1

2

====            #空格追加失败

3

====

4

====

5

====

6

7

8

9

10

[root@centos7 ~]#seq 1 10|sed '2,5a\   ===='                #空格前加”\”斜线

1

2

   ====             #追加空格成功

3

   ====

4

   ====

5

   ====

6

7

8

9

10

-i 在行前插入文本

[root@centos7 ~]#seq 1 10|sed '2,5i\   ===='               #指定行前追加内容

1

   ====

2

   ====

3

   ====

4

   ====

5

6

7

8

9

10

-c 替换指定行文本

[root@centos7 ~]#seq 1 10|sed '2,5c\   ===='               #将指定行替换为指定内容

1

   ====             #替换OK

6

7

8

9

10

w/path/somefile:符合条件的行保存到指定文件

[root@centos7 ~]#seq 1 10|sed '2,5w f1'                   #指定行保存到文件中

1

2

3

4

5

6

7

8

9

10

[root@centos7 ~]#cat f1         #查看保存文件内容

2

3

4

5

-r/path/somefile:读取指定文件的文本到模式空间中,匹配到行后

[root@centos7 ~]#seq 1 10|sed '2,5r /etc/issue'     #读取指定文件追加到指定行后

1

2

\S

Kernel \r on an \m

 

3

\S

Kernel \r on an \m

 

4

\S

Kernel \r on an \m

 

5

\S

Kernel \r on an \m

 

6

7

8

9

10

2.3.3、搜索替换

       s///:查找替换,支持使用其它分隔符s@@@s###

   替换标记:

                     g: 行内全局替换

                     p: 显示替换成功的行

                     w  /PATH/TO/SOMEFILE 将替换成功的行保存至文件中

例子:

[root@centos7 ~]#sed 's/root/admin/' /etc/passwd          #仅替换开头匹配到字符串

admin:x:0:0:root:/root:/bin/bash

[root@centos7 ~]#sed 's/root/admin/g' /etc/passwd         #全局替换

admin:x:0:0:admin:/admin:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

[root@centos7 ~]#sed -r 's/(root)/\1er/g' /etc/passwd  #扩展正则匹配替换

rooter:x:0:0:rooter:/rooter:/bin/bash

[root@centos7 ~]#sed -r 's/(root)/admin\1/g' /etc/passwd  #匹配替换

adminroot:x:0:0:adminroot:/adminroot:/bin/bash

[root@centos7 ~]#sed -r 's/(.*)$/\1mage/g' /etc/passwd         #匹配替换并在结尾增加其他字符串

root:x:0:0:root:/root:/bin/bashmage

bin:x:1:1:bin:/bin:/sbin/nologinmage

daemon:x:2:2:daemon:/sbin:/sbin/nologinmage

[root@centos7 ~]#sed -r 's/(.*)$/mage\1/g' /etc/passwd              #行首前增加字符串

mageroot:x:0:0:root:/root:/bin/bash

magebin:x:1:1:bin:/bin:/sbin/nologin

magedaemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@centos7 ~]#sed -r 's#/(bin/bash)#/s\1#g' /etc/passwd         #匹配替换

root:x:0:0:root:/root:/sbin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

[root@centos7 ~]#seq 1 10|sed '2,5w f1'            #指定行保存到文件中

1

2

3

4

5

6

7

8

9

10

[root@centos7 ~]#cat f1         #查看保存文件中内容

2

3

4

5

练习:

       1)在/etc/default/grub文本中指定行后追加xyz字符串;指定行:GRUB_CMDLINE_LINUX="rhgb quiet"

[root@centos7 ~]#sed -r '/GRUB_CMDLINE_LINUX/ s#(.*)"$#\1 xyz"#g' /etc/default/grub

[root@centos7 ~]#sed -r '/GRUB_CMDLINE_LINUX/ s#"$# xyz"#g' /etc/default/grub 

[root@centos7 ~]#sed -r ' s#^(GRUB_CMDLINE_LINUX=.*)"$#\1 xyz"#g' /etc/default/grub   

GRUB_TIMEOUT=5

GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"

GRUB_DEFAULT=saved

GRUB_DISABLE_SUBMENU=true

GRUB_TERMINAL_OUTPUT="console"

GRUB_CMDLINE_LINUX="rhgb quiet xyz"

GRUB_DISABLE_RECOVERY="true"

       2)使用sedIP地址(ifconfig ens33

[root@centos7 ~]#ifconfig ens33|sed -rn 's#^.*inet (.*)  net.*$#\1#gp'

172.18.118.204

[root@centos7 ~]#ifconfig ens33|sed -rn '2!d;s#^.*inet (.*)  net.*$#\1#gp'

172.18.118.204

[root@centos7 ~]#ifconfig ens33|sed -n '2p'|sed 's/.*inet //g'|sed 's/  net.*//g'        #抛头漏尾方法

172.18.118.204

[root@centos7 ~]#ifconfig ens33|sed -n '2p'|sed -e 's/.*inet //g' -e 's/  net.*//g'            #多点编辑

172.18.118.204

       3)取消指定行带#号的行(/etc/httpd/conf/httpd.conf,需要提前安装httpd服务)

[root@centos6 /media/Packages]#sed -re '/^#NameVirtualHost/s/#//g' -e  '/^#/s/#//g' /etc/httpd/conf/httpd.conf

2.4sed示例

       请说明如下命令作用?

sed ‘2p’ /etc/passwd

sed –n ‘2p’ /etc/passwd

sed –n ‘1,4p’ /etc/passwd

sed –n ‘/root/p’ /etc/passwd

sed –n ‘2,/root/p’ /etc/passwd 2行开始

sed -n ‘/^$/=’ file 显示空行行号

sed –n –e ‘/^$/p’ –e ‘/^$/=’ file

sed ‘/root/a\superman’ /etc/passwd行后

sed ‘/root/i\superman’ /etc/passwd 行前

sed ‘/root/c\superman’ /etc/passwd 代替行

sed ‘/^$/d’ file

sed ‘1,10d’ file

nl /etc/passwd | sed ‘2,5d’

nl /etc/passwd | sed ‘2a tea’

sed 's/test/mytest/g' example

sed –n ‘s/root/&superman/p’ /etc/passwd 单词后

sed –n ‘s/root/superman&/p’ /etc/passwd 单词前

sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets

sed –i.bak ‘s/dog/cat/g’ pets

3、高级编辑命令

3.1、编辑命令参数

P打印模式空间开端至\n内容,并追加到默认输出之前

h: 把模式空间中的内容覆盖至保持空间中

H把模式空间中的内容追加至保持空间中

g: 从保持空间取出数据覆盖至模式空间

G从保持空间取出内容追加至模式空间

x: 把模式空间中的内容与保持空间中的内容进行互换

n: 读取匹配到的行的下一行覆盖至模式空间

N读取匹配到的行的下一行追加至模式空间

d: 删除模式空间中的行

D如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本,并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环

       D删除到第一行换行符前

3.2sed示例

sed -n 'n;p' FILE

命令执行过程:

       默认模式空间为空,先读取第一行内容到模式空间,同时读取下一行到模式空间,根据”n”特性会将下一行的内容覆盖第一行内容,至此执行完n动作并打印输出;以此类推执行编辑命令动作。

例子:

[root@centos7 /app]#seq 1 10|sed -n 'n;p'

2

4

6

8

10

 

sed '1!G;h;$!d' FILE

命令执行过程:

       先读取一行内容,执行地址命令操作,不是第一行的内容从保持空间取出追加到模式空间,因保持空间为空所以不追加到模式空间,执行下一个编辑命令h,把模式空间内容覆盖到保持空间内,最后执行$!d编辑命令操作,不是最后一行的内容删除,执行删除模式空间内容,整个执行过程完成地址命令操作;再读取第2行内容,把不第1行内容从保持空间取出追加到模式空间,追加后再将模式空间内容覆盖到保持空间中,最后执行不是最后一行删除,将模式空间内容进行删除。以此类推执行整个过程,到出结果是以倒序显示。

例子:

[root@centos7 /app]#seq 1 10|sed '1!G;h;$!d'

10

9

8

7

6

5

4

3

2

1

 

sed 'N;D‘ FILE

命令执行过程:

       先读取第1行到模式空间接着下一行追加到模式空间;最后执行D操作,将删除模式空间第1行到换行符,保留第2行在模式空间;模式空间第2行存在接着读取下一行到模式空间,然后再删除第1行到换行符,只保留第3行在模式空间;再读取下一行到模式空间,然后删除第1行内容到换行符,此时文件中内容读取完,而模式空间只剩最后一行并输出最后结果

例子:

[root@centos7 ~]#seq 1 10|sed 'N;D'

10

 

sed '$!N;$!D' FILE

例子:

[root@centos7 ~]#seq 1 10|sed '$!N;$!D'

9

10

 

sed '$!d' FILE

sed ‘G’ FILE

sed ‘g’ FILE

sed ‘/^$/d;G’ FILE

sed 'n;d' FILE

sed -n '1!G;h;$p' FILE