基础语法

命令 功能
a\ 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用”\“续行
i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用”\“续行
d 删除行
h 把模式空间里的内容复制到暂存缓冲区
H 把模式空间里的内容追加到暂存缓冲区
g 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容
G 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的面
l 列出非打印字符
p 打印行
= 打印当前行号
N 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
q 结束或退出sed
r 从文件中读取输入行
! 对所选行以外的所有行应用命令
s 用一个字符串替换另一个
g 在行内进行全局替换
w 将所选的行写入文件
x 交换暂存缓冲区与模式空间的内容
y 将字符替换为另一字符(不能对正则表达式使用y命令)

以下例子中引用的文本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<html>
 <title>Hello sed</title>
 <Switch>
     <username>admin</username>
     <password>482@@lflfdiow</password>
 </Switch>
 <Hello>
     <username>postgres</username>
     <password>hello</password>
 </Hello>
</html>

替换sed默认匹配符/, 任意字符前转义如@= \@, &= \#

  1. 分隔符替换为@, 打印匹配</Switch>

    1
    2
    
    [root@pgmaster home]# sed -n '\@</Switch>@p' test.xml
    </Switch>
  2. 替换@@为##, 紧接着s后面的分隔符不用转义.

    1
    2
    3
    4
    5
    6
    7
    8
    
    sed 's&@@&##&g' test.xml
    <html>
    <title>Hello sed</title>
    <Switch>
        <username>admin</username>
        <password>482##lflfdiow</password>
    </Switch>
    </html>

& 引用匹配变量

word.*word前后加[]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[root@pgmaster home]# sed 's@word.*word@[&]@g' test.xml
<html>
 <title>Hello sed</title>
 <Switch>
     <username>admin</username>
     <pass[word>482@@lflfdiow</password]>
 </Switch>
 <Hello>
     <username>postgres</username>
     <pass[word>hello</password]>
 </Hello>
</html>

打印行数

1
2
[root@pgmaster home]# sed -n '$=' test.xml
11

大小写替换

使用\u表示大写,\l表示小写

  1. 把每个单词的第一个小写字母变大写:
    sed 's/\b[a-z]/\u&/g' filename
  2. 把所有小写变大写:
    sed 's/[a-z]/\u&/g' filename
  3. 大写变小写:
    sed 's/[A-Z]/\l&/g' filename

圆括号匹配

\1, \2分别匹配第一,第二个

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[root@pgmaster home]# sed 's@word>\(.*\)<\(.*\)word@\1-------\2@g' test.xml
<html>
 <title>Hello sed</title>
 <Switch>
     <username>admin</username>
     <pass482@@lflfdiow-------/pass>
 </Switch>
 <Hello>
     <username>postgres</username>
     <passhello-------/pass>
 </Hello>
</html>

合并两行内容

1
2
3
4
5
6
7
[root@pgmaster home]# sed '$!N;s/\n/ /' test.xml
<html>  <title>Hello sed</title>
 <Switch>      <username>admin</username>
     <password>482@@lflfdiow</password>  </Switch>
 <Hello>      <username>postgres</username>
     <password>hello</password>  </Hello>
</html>

打印行数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[root@pgmaster home]# sed '=' test.xml | sed 'N;s/s*\ns*/\t/'
1       <html>
2        <title>Hello sed</title>
3        <Switch>
4            <username>admin</username>
5            <password>482@@lflfdiow</password>
6        </Switch>
7        <Hello>
8            <username>postgres</username>
9            <password>hello</password>
10       </Hello>
11      </html>

删除重复行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[root@pgmaster home]# cat cf.log    
aaaa                                
aaaa                                
bb                                  
bbb                                 
cccc                                
cccc                                
def                                 
ahis                                

[root@pgmaster home]# sed -n '$!N;/^\(.*\)\n\1$/!P;D' cf.log
aaaa
bb
bbb
cccc
def
ahis

删除所有空行

sed '/^$/d' test.txt 或者 sed '/./!d' test.txt
> 解释:都比较简单,第一个匹配空行,第二个匹配非空行。

压缩文件中的连续空行为一行,包括文件开头和结尾(类似cat -s)

sed '/^$/N;/\n$/D' test.txt

每五行后添加一行空行

sed 'n;n;n;n;G'
或者

sed '0~5G' test.txt >解释:很简单,每次读5行,再添加一个空行。第二种方法利用了GNU Sed的功能 addr~step,查看man sed

addr, +N 从匹配行,到+N行。

打印及以下2行内容

1
2
3
4
[root@pgmaster home]# sed -n '\@<Switch>@,+2 p' test.xml
<Switch>
    <username>admin</username>
    <password>482@@lflfdiow</password>

addr, ~N 从匹配行及~N行。

打印至2行内容

1
2
3
[root@pgmaster home]# sed -n '\@</Switch>@,~2 p' test.xml
<Switch>
    <username>admin</username>

addr1, addr2 从第一个匹配行至第二个匹配行

打印两个匹配行之间的内容

1
2
3
4
5
[root@pgmaster home]# sed -n '\@<Switch>@,\@</Switch>@ p' test.xml
 <Switch>
     <username>admin</username>
     <password>482@@lflfdiow</password>
 </Switch>

多个命令集合{}

Switch之间 替换<username>admin</username>root
password行下增加<type>lock</type>
c\, a\ ,其中\是转义空格。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[root@pgmaster home]# sed  '\@<Switch>@,\@</Switch>@{
/username/c\     <username>root</username>
/password/a\     <type>lock</type>
}' test.xml
<html>
 <title>Hello sed</title>
 <Switch>
     <username>root</username>
     <password>482@@lflfdiow</password>
     <type>lock</type>
 </Switch>
 <Hello>
     <username>postgres</username>
     <password>hello</password>
 </Hello>
</html>

反序内容 sed '1!G;h;$!d'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[root@pgmaster home]# sed '1!G;h;$!d' test.xml
</html>
 </Hello>
     <password>hello</password>
     <username>postgres</username>
 <Hello>
 </Switch>
     <password>482@@lflfdiow</password>
     <username>admin</username>
 <Switch>
 <title>Hello sed</title>
<html>