sed编辑器常用操作符:

        s    替换

        d    删除

        i     插入

        a    追加

        c    修改

        y    粘贴

        p    打印

        =    打印行号

        l     列表

        w    写入

        r     读取

        g    替换所有

        q    退出

        n    当前行的下一行

        D    删除模式空间的第一行

        G    加倍行间距

        N    下一行添加到模式空间

        P    只打印模式空间的第一行

        t    分支


使用格式:

        [address]操作符command


sed编辑器使用格式:

sed  options  script  file

        -e    使用多个编辑器命令

        -f     指定文件编辑器命令

        -n    表示禁止输出,使用print命令来完成输出

        -i     修改原文件,直接编辑原文件,且修改后无法还原

例1:echo  "This is a test"  |  sed  's/test/big test/'        替换字符串,test替换为big test

例2:sed  's/dog/cat/'   data.txt                                     替换文件中的字符


多个替换命令:

例:sed  -e  's/brown/green/;   s/god/cat/'  data.txt      使用多个编辑命令

注意:几个命令都是在单引号之内的。


命令写入脚本:

cat  script.sed

s/brown/green/

s/god/cat/

s/fox/elephant/

sed  -f  script.sed  data.txt        使用script.sed文件中的命令处理data.txt文件的内容


替换标记:

s/pattern/replacement/flags

flags       当flags为数字时,这个数字代表要替换掉匹配到的第几个字符串

g            替换所有匹配到的字符串

p            输出修改过的行,与-n一起使用表示只输出修改过的行,-n表示禁止输出

w           将替换结果写到文件中


替换匹配到的第n个字符:

cat  demo.txt

1 This is a test This is a test

2 This is a test This is a test

sed 's/test/apple/2' demo.txt            这个2表示某行中替换匹配到的第二个test

1 This is a test This is a apple

2 This is a test This is a apple


替换结果写入文件:

例:sed  's/test/apple/w  save-data.txt'  demo.txt        会将修改过的行输出到data.txt中

注意单引号将输出的文件名也包括在内


字符串分隔符:

可以自定义字符串分隔符

例1:sed  's/\/bin\/bash/\/bin\/csh/'  /etc/passwd        一般的分隔符

例2:sed  's!/bin/bash!/bin/csh!'  /etc/passwd               自定义分隔符


数字寻址:

单条命令格式:[address]command

多条命令格式:[address]{

        command1

        command2

}

部分匹配寻址:

sed  '2s/dog/cat/'  data.txt            只替换第二行的dog

sed  '2,3s/dog/cat/'  data.txt         替换2到3行的dog

sed  '2,s/dog/cat/'  data.txt           替换第2行之后的所有dog


文本匹配寻址:sed  '/hello/s/dog/cat/'  data.txt    匹配到含有hello的行,将dog替换成cat


同时执行多条命令:

sed  '2{

s/dog/cat/

s/fox/dog/

}'  data.txt

将data.txt中第二行的dog和fox替换成对应的单词


删除行:

sed  'd'  data.txt            删除所有行

sed  '3,d'  data.txt         删除第三行

sed  '3,$'  data.txt         从第三行删除到最后

sed  '3,5'  data.txt         删除3到5行

sed  '/world/d' data.txt          删除包含world的行

sed  '/start/,/end/d' data.txt  删除包含start的字符到包含end的字符之间的所有行,如果文件中有两段这样模式的字符会删除两次,如果未找到结束的end字符,则剩下的全部删除。


插入和附加文本到数据流:

i         insert插入

a        append追加

[address]command\        使用格式


将line 1插入到line2的前面 insert,反斜线不加也可

echo 'hello' | sed 'i\world'
world
hello

将line 1添加到line 2的后面 append

echo 'hello' | sed 'a\world'      
hello
world

将new line插入到数据流的第三行,输出如下:

sed  '3i\This is new line'  data.txt    
This is line number 1.
This is line number 2.
This is new line
This is line number 3.

使用$符号将数据添加到行尾

sed  '$a\new line'  data.txt

将这两行添加到数据流的第一行

sed  '1i\
>new line 1\        #换行使用反斜杠“\”
>new line 2'  data.txt

在文件中指定位置追加:

sed -i '/ExecStart=/a\ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT' /usr/lib/systemd/system/docker.service


修改行:

[address]command\

c    change修改

例1:sed '3c\new worlds' data.txt             将数据流的第三行修改为new worlds

例2:sed  '/dog/c\ cat'  data.txt                将数据流中匹配到的dog行全部修改为cat

例3:sed  '2,5c\dog\cat'  data.txt              将2到5行的数据替换为新的数据


转换命令/单字符替换:

y        单字符一对一替换,使用格式[address]y/inchars/outchars/

例:sed  'y/ab/cd/' data.txt                       将全部数据流中的a替换成c,b替换成d,如果要替换的字符长度不对应会报错,只能指定行到行之间替换,无法指定某一行的单独位置替换。


打印行:

p        简单的打印行

例1:echo  "This  is a test" |  sed  'p'       将输出的打印

例2:sed  -n  '/hello/p'  data.txt              打印出匹配到的

例3:sed  -n  '2,3p'  data.txt                    只打印出指定的行

例4:

sed  -n  '/hello/{           #匹配到有hello的行

>p                                #先显示修改之前的

>s/hello/world/p         #再显示出修改之后的

}'  data.txt


打印行号:

=        可以打印出数据流的行号,以换行符为准

例:sed '='  data.txt

例:

sed  -n  '/three/{

=            #打印行号

p            #打印查找到的行

}' data.txt


列出行:

l        可以打印出数据流中的换行符制表符等,字母L的小写

例:sed  -n  'l'  data.txt


数据写入文件:

[address]w  filename

w        向文件中写入数据

例:

sed  '2,5w  demo.txt'  data.txt                   将data.txt中的第2到5行写入demo.txt文件中

sed  -n  '/hello/w demo.txt'  data.txt        将包含有hello的行写入demo.txt中


从文件中读取数据:

[address]r  filename

r    将文件中的数据插入到数据流中

例1:sed  '3r  demo.txt'  data.txt             将demo.txt中的文本插入到数据流的第3行

例2:sed  '/hello/r  demo.txt'  data.txt    将demo.txt中的数据插入到数据流的hello字符后面

例3:sed  '$r demo.txt' data.txt               将demo.txt中的数据插入到数据流的最后


例4:将文件添加到占位符的位置,并删除占位符

数据流中的文件:

cat  data.txt

Would the following people:

LIST

please report tp the ship's captain.

列表文件:

cat  list.txt

Hello

world

将列表替换原来的LIST占位符:

sed '/LIST/{

    r  list.txt

    d

}' data.txt

替换的结果为:

Would the following people:

Hello

world

please report tp the ship's captain


next命令:

n            next找到当前行的下一行

例:sed  '/hello/{n ; d}' data.txt        找到当前行的下一行,并删除,n命令会指向下一行,d命令执行删除


合并文本行:

N           将下一行添加到sed编辑器的工作空间。

sed '

>s/System Adminstrator/Desktop User/             #替换单行的情况

>N

>s/System\nAdminstrator/Desktop\nUser/        #替换句子分布在多行的情况

'  data.txt


多行删除命令:

D            删除模式空间中的第一行,经常和N命令一起使用

sed  'N ; /hello\nworld/D'  data.txt          匹配到hello world的两行,再删除包含有hello的行

sed  '/^$/{N ; /header/D}'  data.txt          删除header行上一行的空白


多行打印命令:

P            只打印模式空间的第一行

sed  -n  'N ; /hello\nworld/P' data.txt


保持空间:

sed编辑器有两个缓冲区,模式空间和保持空间

操作保持空间的命令

h        将模式空间复制到保持空间

H        将模式空间附加到保持空间

g        将保持空间复制到模式空间

G        将保持空间附加到模式空间

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


排除命令:

!            不执行匹配的行,取消命令

sed  -n  '/hello/!p'  data.txt                    除了包含hello的行不打印,其他的都打印出来

sed  -n  '{1!G ; h ; $p }'  data.txt             反转输出文本内容,类似tac命令


分支命令:

[address]b [label]        b放在寻址的后面

例:

cat  data.txt

this xxx xxx xxx xxx

this xxx xxx xxx xxx

xxxx xxx bbb xxx xxx

sed命令写法:

sed '{

/bbb/b jump ;        #匹配到bbb就跳转到jump位置,并执行jump后面的命令

s/this/xxx/ ;            #其他行执行的命令

:jump ;                    #冒号后面放label标签

s/bbb/XXX/ ;

}' data.txt

处理结果:

xxx xxx xxx xxx xxx

xxx xxx xxx xxx xxx

xxxx xxx XXX xxx xxx


测试:

[address]t [label]        同判断语句

例:

sed '{

s/hello/xxx/        #如果成功替换了这条,就不执行下一条替换,否者执行下一条替换

t

s/world/xxx/

}'  data.txt

无限循环示例:

sed -n '{

:start

s/hello/xxx/1p        #如果替换成功就会跳转到start再次执行替换,1表示匹配到的第一个

t start

}'  data.txt

跳转符号最长为7个字符。


模式替代:

&符号

同正则中的 \1  \2

echo "This is a cat"  |  sed  's/.at/"&"/g'


子模式:

\1  \2            如同正则中的子模式

例1:echo "This is a cat" | sed 's/\(.at\)/"\1"/g'

例2:在数字中插入逗号

echo "123456" | sed '{

:start

s/\(.*[0-9]\)\([0-9]\)\{3\}/\1,\2/

t start

}'

处理结果:1,234,567


在脚本中使用sed:

包装sed脚本:

在脚本reverse.sh中写入:

sed -n '{ 1!G ; h ; $p }'  $1

这个$1参数用来接收要处理的文件名称,这样就不用每次都输入sed命令了,这个脚本功能同tac


重定向sed输出:

一个计算阶乘的示例:

#!/bin/bash

factorial=1

counter=1

number=$1

while [ $counter -le $number ]

do

        factorial=$[ $factorial * $number ]

        counter=$[ $counter + 1 ]

done

result=$(echo $factorial | sed '{

:start

s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/

t start

}')

echo "The result is $result"


创建sed实用工具:

G        加倍行间距:

sed  'G'  data.txt            在文本的每行后面插入一个空行

sed  '$!G'  data.txt         最后一行不使用G命令,也就是说除了最后一行在每行后面都加入一个空行,$最后一行 !跳过

这个方法的技巧在于启动sed编辑器之后保持空间中只有一个空行。


对有空行的文本加空行:

问题的关键在于有两个空行的行就不用加倍空行了,所以要先删除空行,再加文本空行。

sed  '/^$/d ; $!G'  data.txt        先将所有的空行都删除了,然后将除了最后一行之外的其他行都加空行。


给文件中的行编号:

sed '=' test.txt | sed 'N ; s/\n/ /'        等于号=可以输出序号,但是有换行,再使用另一个sed命令处理掉换行,用N命令合并两行,再将换行替换掉


打印末尾行:

sed  '{

>:start

>$q                #$ 最后一行,q退出,表示遇到最后一行就退出sed,q命令是退出命令

>N                 #N将下一行追加到模式空间

>11,$D           #11,$D是当模式空间中有11行后,D命令就会删除空间中第一行

>b start          #循环上面的过程

>}' test.txt

这样就会得到最后的10行文本内容


删除行


删除连续的空白行:

sed  '/./,/^$/!d'  data.txt        /./表示开始区间必须不是空白行,/^$/结束区间是空白行,!d表示不删除,连起来就是区间内的空白行不会被删除,如果文本有两个以上的空白行只会一个空白行。


删除开头的空白行:

sed  '/./,$!d' data.txt        /./表示非空行的开始区间,$表示最后一行,!d表示不删除;意思就是从有内容的行开始到最后一行都不删除,这样只有开头的空白行才会被删除了。


删除注释和空行:

sed '/^#\|^$/d' demo.conf


删除结尾的空行:

sed  '{

:start

/^\n*$/{$d ; N ; b start}            /^\n*$/这个能匹配只含有一个换行符的行

}'

$d表示是最后一行就删除,N将下一行附加到模式空间,这样每一次循环就删除最后一行空行。

注意:括号中包括括号,这是命令分组,可以将该组命令只作用在地址区间中。


显示奇数行:

sed -n '1~2p' data.txt        使用1~2表示步进地址,1表示从第一行,2表示步进为2,显示偶数可以使用2~2表示。


删除HTML标签:

sed 's/<[^>]*>//g'  data.txt

sed 's/<[^>]*>//g ; /^$/d'  data.txt        顺带删除空行