Linux-sed总结

命令汇总

指令含义
a在当前行后面加入一行文本
b lable跳转分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末
c用新的文本改变本行的文本
d从模式空间(Pattern space)位置删除行
D删除模板块的第一行
i在当前行上面插入文本
h拷贝模式空间的内容到保持空间(hold space),替换之前的内容
H将模式空间的内容追加到保持空间,追加为\n
g获取保持空间中的内容,并覆盖当前模式空间的内容
G后去保持空间中的内容,将内容追加到模式空间之后
l列出不能打印的字符
n读取下一行的内容,替换当前行
N读取下一行的内容,追加到当前行之后,即 \n 下一行的内容
p打印模式空间的内容
P(大写)打印模式空间的第一行
q退出sed
r file从指定的文件中读取内容
ss/re/string  用string替换正则表达式re,s/re/string/g 表示替换所有处
t lable

如果之前的模式满足条件,则执行t 并跳转到指定的标签出,如果t 没有

标签则跳转到表达式最后(也就是结束什么都不做)

T lable和t 指令相反,当前面的模式没有满足条件时,才进行跳转
w file将模式空间中的内容append到指定的文件后
W file将模式空间中的第一行append到指定的文件后
x互换模式空间和保持空间的内容
y

类似tr命令,y/old/new/ 将old替换成new,这里是按字母匹配的,所以

old和new的长度必须一样

 

 

 

 

 

选项

选项含义
-e进行多项编辑,即对输入行应用多条sed命令时使用
-n取消默认的输出
-f指定sed脚本的文件名(sed的表达式放在一个文件中)
-r使用扩展正则表达式

 

 

 

 

 

元字符集

元字符含义
^锚定行的开始如:/^sed/匹配所有以sed开头的行
$锚定行的结束 如:/sed$/匹配所有以sed结尾的行
.匹配任意一个字符
[]匹配指定范围内的字符
\(..\)保存匹配的字符,如s/\(love\)able/\1rs,\1可以引用第一个圆括号的内容
&用来当做被匹配的变量
\<锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行
\>锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行
x\{m\}重复字符x,m次,如:/0\{5\}/匹配包含5个o的行
x\{m,\}重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行
x\{m,n\}重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行

 

 

 

 

 

指令详解

a指令

  1. #在所有行后增加...  
  2. seq 10 | sed 'a ......'  
  3.   
  4. #在2,3行之后增加 ??  
  5. seq 10 | sed '2,3 a ??'  


b指令

  1. #如果是匹配 3则只在最后增加 !!!,其他行在尾后增加@@@和 !!!  
  2. #b标签是强制跳转,不像t标签满足条件后才跳转,b是任何情况下都跳转  
  3. seq 10 | sed '/3/b lable; s/$/ @@@/; :lable s/$/ !!!/'  
  4. #结果  
  5. 1 @@@ !!!  
  6. 2 @@@ !!!  
  7. 3 !!!  
  8. 4 @@@ !!!  
  9. 5 @@@ !!!  
  10. 6 @@@ !!!  
  11. 7 @@@ !!!  
  12. 8 @@@ !!!  
  13. 9 @@@ !!!  
  14. 10 @@@ !!!  

 

i指令

  1. #在第三行之前增加 ???  
  2. seq 10 | sed '3 i ???'  
  3.   
  4. #在第一到第五行之前增加hehe  
  5. seq 10 | sed '1,5 i hehe'  
  6.   
  7. #如果是8开头的,则在这行之前增加hehe  
  8. seq 10 | sed '/^8/ i hehe'    
 

 

h,H,g,G指令

  1. seq 3 | sed 'H;g'  
  2. #结果为  
  3.   
  4. 1  
  5.   
  6. 1  
  7. 2  
  8.   
  9. 1  
  10. 2  
  11. 3  
  12.   
  13. seq 3 | sed 'h;G'  
  14. #结果  
  15. 1  
  16. 1  
  17. 2  
  18. 2  
  19. 3  
  20. 3  
  21.   
  22. seq 3 | sed -n '1!G; h; $p'   
  23. #结果  
  24. 3  
  25. 2  
  26. 1  

 

seq 3 | sed 'H;g' 执行步骤:

操作模式空间保持空间
H1\n1
g\n1\n1
H2\n1\n2
g\n1\n2\n1\n2
H3\n1\n2\n3
g\n1\n2\n3\n1\n2\n3

 

seq 3 | sed 'h;G' 执行步骤

操作模式空间保持空间
h11
G1\n11
h22
G2\n22
h33
G3\n33

 

seq 3 | sed -n '1!G; h; $p' 执行结果

操作模式空间保持空间
1!G1 
h11
$p------
1!G2\n11
h2\n12\n1
$p------
1!G3\n2\n12\n1
h3\n2\n13\n2\n1
$p3\n2\n1 

 

 

l 指令

  1. #显示不可打印字符  
  2. cat /etc/man.config | head | sed -n 'l'  

 

n和N指令

  1. #打印偶数行,n将下一行的内容读取替换当前行  
  2. seq 11 | sed -n 'n; p'  
  3. #结果  
  4. 2  
  5. 4  
  6. 6  
  7. 8  
  8. 10  
  9.   
  10. #打印基数行,N将下一行的内容读取然后append到当前行后面,P(大写)打印模式空间中第一行  
  11. seq 12 | sed -n '$!N; P'  
  12. 1  
  13. 3  
  14. 5  
  15. 7  
  16. 9  
  17. 11  
 

p和P指令

  1. seq 11 | sed -n 'N; P'  
  2. seq 12 | sed -n '$!N; P'  
  3. #从这两段打印偶数,基数的代码中可以看出p和P(大写)的区别  
  4. #p是打印模式空间中所有的内容,而P只打印第一行  

 

q指令

  1. #当匹配 3这行时,退出sed  
  2. seq 10 | sed '/3/q;'   

 

r指令

  1. #当匹配10这一行时,读取xx.log文件  
  2. seq 10 | sed '/10/r xx.log'  
  3. #结果  
  4. 1  
  5. 2  
  6. 3  
  7. 4  
  8. 5  
  9. 6  
  10. 7  
  11. 8  
  12. 9  
  13. 10  
  14. 11111  
  15. 22222  
  16. 33333333333  
  17. 4444444444444  
  18. ffffff  

 

s指令

  1. #匹配这行第四个和第五个aaa,将其替换为AAA,这里使用了多个匹配  
  2. #两个匹配之间用分号分隔, 注意两个匹配式是一样的,因为第一次匹配完之后  
  3. #内容就变了  
  4. echo "aaa bbb aaa aaa ccc ddd aaa aaa aaa " | sed 's/aaa/AAA/4; s/aaa/AAA/4;'  
  5.   
  6. #匹配这行所有出现的aaa  
  7. echo "aaa bbb aaa aaa ccc ddd aaa aaa aaa " | sed 's/aaa/AAA/g'    
  8.   
  9. #匹配第一到第二行,将所有的1替换为!  
  10. sed '1,2s/1/!/g' xx.log  
  11.   
  12. #匹配第三行到最后一行,将所有的1替换为!  
  13. sed '3,$s/1/!/g' xx.log    

 

t和T指令

  1. #将第三行替换为three,其他行替换为ok  
  2. seq 5 | sed  's/3/three/; t lable; s/[0-9]/ok!/; :lable'  
  3.   
  4. #T标签和t相反,当前面的表达式没有匹配时才跳转到lable标签  

 

w指令

  1. #匹配3,将结果写入到xx.log中  
  2. seq 5 | sed -n '/3/w xx.log'  

 

x指令

  1. #交换模式空间和保持空间的内容  
  2. #第三行的模式空间和保持空间交换后,模式空间为空  
  3. #第四行和保持空间交换,此时保持空间内容为3,所以最终模式空间内容变为3  
  4. seq 5 | sed '3,4 x;'  
  5. #结果  
  6. 1  
  7. 2  
  8.   
  9. 3  
  10. 5  

 

y指令

  1. #匹配bbb,替换为BBB  
  2. #注意y指令是按字符替换的,所以匹配前的字符和匹配后的字符长度应该相等  
  3. echo "aaa bbb ccc" | sed 'y/bbb/BBBB/'  

 

打印当前行号

  1. #当匹配f时,用= 指令打印当前行号  
  2. for i in {a..j}; do echo $i; done | sed -n '/f/='  

 

& 符号

  1. # & 符号表示被匹配的变量  
  2. for i in {a..j}; do echo $i; done | sed 's/f/---> & <---/;'     


{} 匹配

  1. #匹配a,至少3-5次  
  2. echo "xxx aaaaaa fff " | sed 's/a\{3,5\}/!!!/'  
  3.   
  4. #可以用扩展正则表达式实现  
  5. echo "xxx aaaaaa fff " | sed -r 's/a{3,5}/!!!/'  

 

\< 和 \>

  1. #匹配k开头的单词,和k结尾的单词  
  2. echo "aaa bbb kkk ccc ddd" | sed 's/\<k/***/; s/k\>/###/'   

 

圆括号匹配

  1. #假设file中都是数字,匹配前两个数字,将十位数,变成个位数+一个小数点和数字  
  2. sed 's/\([0-9]\)\([0-9]\)/\1.\2/' file.txt  
  3.   
  4. #上面的() 需要转义,可以用扩展正则表达式来完成同样的功能  
  5. sed -r 's/([0-9])([0-9])/\1.\2/' file.txt  

 

多个匹配和子匹配

  1. #匹配多个,也可以用-e 来实现  
  2. echo "xxx aaaaaa fff " | sed -r 's/a/A/; s/x/X/; s/ /--/'  
  3. #结果  
  4. Xxx--Aaaaaa fff   
  5.   
  6. #子匹配,如果匹配3,则执行子匹配, 读取下一行append到模式空间  
  7. #如果又匹配4,则再执行子匹配打印当前模式空间内容; 如果匹配5则执行子匹配  
  8. #删除当前模式空间内容  
  9. seq 5 | sed -n '/3/{N; /4/{p;}; /5/{d}; }'  
  10. #结果  
  11. 3  
  12. 4  
  13. #删除匹配的结果 /[匹配的表达式]/  
  14. seq 10 | sed '/3/d'  

 

 

 

 

 

一些实际的例子

交换奇偶行

  1. seq 10 | sed -n 'x;n;p;x;p'  

执行步骤

操作模式空间保持空间
xnull1
n21
p21
x12
p12

 

另一种方式

  1. seq 10 | sed -n 'h;$!{n;G};p'  

操作步骤

操作模式空间保持空间
h11
$!{n21
G}2\n11
p2\n11

 

 

将所有行合并成一行

  1. seq 10 | sed -n '1{h};1!{H};${g;;s/\n/ /g;p}'  

操作步骤

操作模式空间保持空间
1{h}11
1!{H}11
${....}11
1{h}11
1!{H}21\n2
${...}21\n2
.............
${....}1\n2\n3...1\n2\n3...

 

另一种方式

  1. seq 10 | sed -n 'h;:lable n;H;$!{b lable};x;s/\n/ /g;p'  

首先执行h,将模式空间内容覆盖到保持空间

之后执行lable标签,n 将下一行的内容覆盖到当前行,然后将模式空间内容append到保持空间

如果不是最后一行,则执行跳转标签继续重复n;H; 执行

到最后一行执行x指令,此时模式空间内容就是1\n2\n3\n4\n..., 再执行s执行替换\n 之后打印

 

 

 

 

 

参考

sed(linux指令)

sed的保持空间和模式空间

关于sed的模式空间和保持空间的例子

sed之lable使用详解

sed简明教程

sed系列文件

sed英文手册 

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页