【Shell】Shell编程之sed命令

sed介绍

sed编辑器是被称为流编辑器。它被用来在输入流(文件或者从管道输入)上进行基本的文本转换。处理时,把当前处理的行存储在临时缓冲区,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出,sed主要用啦爱自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等。

sed命令行选项

sed命令完整格式:
sed OPTIONS ... [SCRIPT] [INPUTFILE...]
命令行选项有以下:
--version:显示版本信息;
-n --quiet --silent:只打印脚本处理后的结果;
-e --expression=script:以选项中指定的script处理输入的文件;
-f script-file或--file=script-file:以选项中指定的文件处理输入的文件;
-i [SUFFIX]或--in-place[=SUFFIX]:直接修改文档读取的内容,不会输出到屏幕;
-r或--regexp-extended:sed使用扩展正则。

sed退出状态

退出状态为0表示成功,非零值表示失败。
0:成功完成;
1:无效的命令,无效的语法或者无效的正则表达式;
2:命令行中指定的文件不能被打开(比如文件找不到或者没有权限),继续处理其他文件;
4:I/O错误或者运行时严重的处理错误;

sed元字符集

^:匹配行开始,如:/^sed/匹配所有以sed开头的行;
$:匹配行结束,如:/sed$/匹配所有以sed结尾的行;
.:匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d;
* :匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行;
[]:匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed; 
[^]:匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行;
\(..\):匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers;
&:保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**;
\<:匹配单词的开始,如:/\
\>:匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行;
x\{m\}:重复字符x,m次,如:/0\{5\}/匹配包含5个0的行;
x\{m,\}:重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行;
x\{m,n\}:重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。

sed命令

可通过man sed查看该命令的详细参数信息:
[root@strong sed_stu]# man sed

sed命令演示

测试数据
[root@strong sed_stu]# cat emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
[root@strong sed_stu]# 
1、打印:p命令
--打印第一行信息
[root@strong sed_stu]# sed '1p' emp.txt 
0001  Alen   M  24
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
默认情况下,会把输入行打印到屏幕上,选项-n取消默认打印,-n和p一起使用时只打印选定的内容:
--打印第一行
[root@strong sed_stu]# sed -n '1p' emp.txt 
0001  Alen   M  24
--打印第三行到第五行的记录
[root@strong sed_stu]# sed -n '3,5p' emp.txt 
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
--打印包含Tim的行
[root@strong sed_stu]# sed -n '/Tim/p' emp.txt 
0005  Tim    M  25
--打印Tim开始到Bobo之间的行
[root@strong sed_stu]# sed -n '/Tim/,/Bobo/p' emp.txt 
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
2、删除:d命令
--删除第五行,默认情况下,其余行会被打印到屏幕上
[root@strong sed_stu]# sed '5d' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--删除第三行到最后一行的记录
[root@strong sed_stu]# sed '3,$d' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
--删除包含模式Felix到Geo的行
[root@strong sed_stu]# sed '/Felix/,/Geo/d' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0009  Andy   F  19
00010 Peter  M  28
3、替换:s命令
--将文本里的2替换为222
[root@strong sed_stu]# sed 's/2/222/' emp.txt 
0001  Alen   M  2224
000222  Tiboo  M  32
0003  Felix  M  2226
0004  Jack   F  2224
0005  Tim    M  2225
0006  Audi   F  30
0007  Bobo   F  3222
0008  Geo    M  2221
0009  Andy   F  19
00010 Peter  M  2228
--替换标识为数字2,表示替换第二次出现的
[root@strong sed_stu]# sed 's/2/....222/2' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  3....222
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
注:本例替换的是行中出现的第一次2的值为222,如果替换正行的记录,则需要和g一起使用,表示全局替换。
--替换标识为g,表示用新文本替换现有文本的全部实例
[root@strong sed_stu]# sed 's/2/222/g' emp.txt 
0001  Alen   M  2224
000222  Tiboo  M  3222
0003  Felix  M  2226
0004  Jack   F  2224
0005  Tim    M  2225
0006  Audi   F  30
0007  Bobo   F  3222
0008  Geo    M  2221
0009  Andy   F  19
00010 Peter  M  2228
---替换标识p,表示打印原始行的内容
[root@strong sed_stu]# sed -n 's/2/222/gp' emp.txt 
0001  Alen   M  2224
000222  Tiboo  M  3222
0003  Felix  M  2226
0004  Jack   F  2224
0005  Tim    M  2225
0007  Bobo   F  3222
0008  Geo    M  2221
00010 Peter  M  2228
--替换标识为w file,表示将替换的结果写入文件
[root@strong sed_stu]# sed 's/2/....222/w test.txt' emp.txt 
0001  Alen   M  ....2224
000....222  Tiboo  M  32
0003  Felix  M  ....2226
0004  Jack   F  ....2224
0005  Tim    M  ....2225
0006  Audi   F  30
0007  Bobo   F  3....222
0008  Geo    M  ....2221
0009  Andy   F  19
00010 Peter  M  ....2228
[root@strong sed_stu]# cat test.txt 
0001  Alen   M  ....2224
000....222  Tiboo  M  32
0003  Felix  M  ....2226
0004  Jack   F  ....2224
0005  Tim    M  ....2225
0007  Bobo   F  3....222
0008  Geo    M  ....2221
00010 Peter  M  ....2228
--在Felix和Audi之间的末尾加上***HI****
[root@strong sed_stu]# sed '/Felix/,/Audi/s/$/***HI****/' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26***HI****
0004  Jack   F  24***HI****
0005  Tim    M  25***HI****
0006  Audi   F  30***HI****
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
4、使用多个编辑器命令:e命令
[root@strong sed_stu]# sed -e 's/Alen/ALEN/;/Jack/,/Audi/s/$/****HI****/' emp.txt 
0001  ALEN   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24****HI****
0005  Tim    M  25****HI****
0006  Audi   F  30****HI****
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--或者分开使用-e
[root@strong sed_stu]# sed -e 's/Alen/ALEN/' -e  '/Jack/,/Audi/s/$/****HI****/' emp.txt 
0001  ALEN   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24****HI****
0005  Tim    M  25****HI****
0006  Audi   F  30****HI****
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--使用次提示符
[root@strong sed_stu]# sed -e '
> s/Alen/ALEN/
> /Jack/,/Audi/s/$/****HI***/' emp.txt
0001  ALEN   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24****HI***
0005  Tim    M  25****HI***
0006  Audi   F  30****HI***
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
5、从文件读取编辑器命令
--sed命令
[root@strong sed_stu]# cat script.txt 
s/Alen/ALEN/
/Jack/,/Audi/s/$/****HI****/
---f指定sed脚本文件
[root@strong sed_stu]# sed -f script.txt emp.txt 
0001  ALEN   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24****HI****
0005  Tim    M  25****HI****
0006  Audi   F  30****HI****
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
6、附加文本:a命令
--在指定行之后添加一行
[root@strong sed_stu]# sed '3a\This is append test' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
This is append test
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
7、插入文本:i命令
[root@strong sed_stu]# sed '3i\This is inserted line' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
This is inserted line
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
8、更改行:c命令
--修改整行文本内容
[root@strong sed_stu]# sed '3c\This is updated by new line' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
This is updated by new line
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
9、删除行:d命令
[root@strong sed_stu]# sed '1,5d' emp.txt 
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
10、变换行:y命令
[root@strong sed_stu]# sed '1,5y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' emp.txt 
0001  ALEN   M  24
0002  TIBOO  M  32
0003  FELIX  M  26
0004  JACK   F  24
0005  TIM    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
11、获取下一行:n命令
--获取Jack的下一行,并用....2222替换2
[root@strong sed_stu]# sed '/Jack/{n;s/2/....2222/;} ' emp.txt
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  ....22225
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--删除空行
[root@strong sed_stu]# cat emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26

0004  Jack   F  24
0005  Tim    M  25

0006  Audi   F  30
0007  Bobo   F  32

0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--删除Felix下一行的空格
[root@strong sed_stu]# sed '/Felix/{n;d}' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25

0006  Audi   F  30
0007  Bobo   F  32

0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
--删除所有空格
[root@strong sed_stu]# sed '/^$/d' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0003  Felix  M  26
0004  Jack   F  24
0005  Tim    M  25
0006  Audi   F  30
0007  Bobo   F  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
12、组合多行文本:N命令
--在数据流中添加下一行以创建用于处理的多行组
[root@strong sed_stu]# sed '/Alen/{N;s/\n/ /;}' emp.txt 
0001  Alen   M  24 0002  Tiboo  M  32
0003  Felix  M  26

0004  Jack   F  24
0005  Tim    M  25

0006  Audi   F  30
0007  Bobo   F  32

0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
13、否定命令:!命令
--输出不在3行和7行之间的数据行
[root@strong sed_stu]# sed -n '3,7!p' emp.txt 
0001  Alen   M  24
0002  Tiboo  M  32
0008  Geo    M  21
0009  Andy   F  19
00010 Peter  M  28
14、模式替换
--&表示替换命令中的匹配模式
--给某个单词加引号
[root@strong sed_stu]# echo "The cat sleeps in his hat" | sed 's/.at/"&"/g'
The "cat" sleeps in his "hat"
--使用圆括号定义替换模式中的子字符串元素,然后用特定符号引用,替换字符由反斜杠和数字组成
[root@strong sed_stu]# echo "This is Alen Liu , not Alen Li" | sed 's/\(Alen\) Liu/\1 L/' 
This is Alen L , not Alen Li



你可能感兴趣的:(Linux系列,-----【Shell编程】)