sed 流编辑器
行编辑器,逐行处理 (全屏编辑器:vi )
模式空间
默认不编辑源文件,仅对模式空间中的数据做处理
1、StartLine,EndLine 1,100
2、/RegExp/ /^root/
3、/pattern1/,/pattern2/
4、LineNumber 指定的行
5、StartLine,+N 从指定的行开始,向后的N行
command :
-n : 静默模式,不再默认显示模式空间的内容
-i : 直接修改源文件
-e : 可以同时执行多个脚本
-f :
-r :表示扩展正则表达式
address:
q :执行完后匹配的直接退出
d:删除符合条件的行
p:显示符合条件的行 与 n 一起用
a \string :在指定的行后追加新行,内容为string
i:\string: 在指定的行前面追加新行,内容为string
r FILE :将指定文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中
s/pattern/string/修饰符 :查找并替换,默认只替换每行中第一次被模式匹配到的字符串
加修饰符
g: 全局替换
i:忽略字符大小写
\( \) \1 后项引用
高级用法
保留空间
hold space : 保留空间,初始为空
pattern space : 模式空间
command:
n: 将模式空间拷贝与标准输出,用输出的下一行替换模式空间。
N: 把输入的下一行添加的模式空间中
p:打印模式空间里的行
P:打印模式空间里的第一行
[root@cluster-node1 yanf]# sed -n 'N;p' sed
1(a)
2(b)
3(c)
4(d)
[root@cluster-node1 yanf]# sed -n 'N;P;' sed
1(a)
3(c)
N是把输入的下一行添加到模式空间,而小p则是打印模式空间里的行 ,模式空间读取第一行,N下一行输入到模式空间,所以模式空间里的内容为 1(a) 2(b) ,小p是打印全部,所以全部输出,而P则是打印模式空间里的第一行,所以输出第一和第三行,也就是奇数行。
[root@cluster-node1 yanf]# sed -n 'n;p' sed
2(b)
4(d)
n是将模式空间拷贝到保留空间,用输出的下一行替换模式空间,n匹配第一行时模式空间里内容为 2(b) 接着运行第三行时模式空间里的内容为4(d),所以打印出来内容为偶数行
G:将保留空间内容追加到文件中的每一行后面,由于保留空间默认值为空,所以每一行后面多了一个空行
g:将保留空间内容替换当前文件中的文本
[root@cluster-node1 yanf]# sed G sed
1(a)
2(b)
3(c)
4(d)
[root@cluster-node1 yanf]# sed g sed
保留空间的初始默认值为空,因为G追加到文本中每行后面,所以每一行后面多了一行空行 ,g 是将保留空间内容替换当前文本行,因为保留空间的初始默认值为空,所以输出为空。
d:从模式空间位置删除行
D: 删除模式空间的第一行
[root@cluster-node1 yanf]# sed 'N;d' sed
[root@cluster-node1 yanf]# sed 'N;D;' sed
4(d)
N将下一行添加至模式空间,所以模式空间就有两行,d是将模式空间所有都删除,所以没有输出,D是将模式空间的第一行删除,所以执行下来的话就只剩最后一行没有被删除,故而打印出最后一行
h:将模式空间的内容拷贝到保留模式中
H:将模式空间的内容追加到保留模式中
[root@cluster-node1 yanf]# sed '1!G;h;$!d' sed
4(d)
3(c)
2(b)
1(a)
[root@cluster-node1 yanf]# sed '1!G;H;$!d' sed
4(d)
1(a)
2(b)
1(a)
3(c)
1(a)
2(b)
1(a)
看一下 sed '1!G;h;$!d' 命令执行过程中保留空间与模式空间的变化:
命令 保留空间 模式空间
第一行 h;d 执行前:null 执行后:1(a)\n 执行前:1(a) \n 执行后:null
第二行 G;h;d 执行前:1(a)\n 执行后:2(b)\n1(a)\n 执行前:2(b)\n 执行后:null
第三行 G;h;d 执行前:2(b)\n1(a)\n 执行后:3(c)\n2(b)\n1(a)\n 执行前:3(c) 执行后:null
第二行 G;h; 执行前:3(c)\n2(b)\n1(a)\n 执行后:4(d)\n3(c)\n2(b)\n1(a)\n 执行前:4(d)\n 执行后:4(d)\n3(c)\n2(b)\n1(a)\n
此功能使文件倒序排列
x:交换模式空间和保留空间的内容
[root@cluster-node1 yanf]# sed '/a/{x;p;x;}' sed
1(a)
2(b)
3(c)
4(d)
[root@cluster-node1 yanf]# sed '/a/{x;p;}' sed
2(b)
3(c)
4(d)
[root@cluster-node1 yanf]# sed '/a/{p;x;}' sed
1(a)
2(b)
3(c)
4(d)
命令 保留空间 模式空间
x 执行前null,执行后 1(a) 执行前1(a) ,执行后null
p 执行前null,执行后 1(a) 执行前1(a) ,执行后null 因为模式空间为空所以打印出模式空间的空行
x 执行前1(a) ,执行后null 执行前null,执行后 1(a)
第一条命令 全部执行了,所以输出在最前面插入了空行
第二条命令执行了x,p 打印出空行后,模式空间还是为空,所以输出两个空行
第三条命令p,x 先把匹配到a的行打印出来,然后跟保留空间互换,模式空间为空,所以输出为在匹配行后插入空行
实例:
打印文档奇数行
sed 'n;d' ###将文档所有偶数行删除,剩下的都是奇数行
sed 'x;$!N;x'
sed -n 'p;n'
打印偶数行
sed -n 'n;p'
sed '1d;n;d;
删除连续重复行 (大量使用模式空间,文件太大时注意使用)
sed '$!N; /^\(.*\)\n\1$/!P; D' #使用 $!N 要当心内存溢出
合并上下行
sed '$!N;s/\n/ /'
将以\符号结尾的行与下行合并并以空格分隔(拼接断行)
sed -e :a -e '/\\$/N; s/\\\n/ /; ta'
显示匹配行的行号并输出匹配行的上行、匹配行、下行
sed -n -e '/regexpr/{=;x;1!p;g;$!N;p;D;}' -e h
分解日期串
echo 20030922|sed 's/\(....\)\(..\)\(..\)/\1 \2 \3/'|read year month day
echo $year $month $day 2003 09 22
sed 标签使用
sed里面有几个标签操作,和goto有点像,这里简单记录下 :
b ----跳到指定标签(即执行标签后面的指令),b后不跟任何东西,表示跳到结尾
t ----- 后不跟任何标签,如果前面的符合就会跳到结尾,否则执行t后面的指令
T -----后不跟任何标签,和t相反,如果前面匹配为假则跳去""即脚本结尾
例子如下:
cat file
A
B
1、sed '/^A/b a;s/$/ Y/;:a;s/$/ N/' file #如果匹配上A,就会跳到标签a处执行a后的指令s/$/ N/,如果不匹配执行s/$/ Y/;:a;s/$/ N/
执行结果 :
A N
B Y N
2、 sed '/^A/b a;s/$/ Y/;b;:a;s/$/ N/' file #如果匹配上A,就会跳到标签a处执行a后的指令s/$/ N/,如果不匹配执行s/$/ Y/;遇到b跳"",既执行到脚本末尾,则跳过了命令 s/$/ YES/
执行结果 :
A N
B Y
3、sed '/^A/s/$/ Y/;t;s/$/ N/' file # 如果匹配上A,就会执行s/$/ Y/,然后遇到t跳至""即脚本末尾
执行结果 :
A N
B Y
4、sed '/^A/s/$/ Y/;T;s/$/ N/' file # 如果匹配上A,就会执行s/$/ Y/,然后遇到T继续执行s/$/ N/,如果不匹配则直接跳去末尾
执行结果 :
A Y N
B
阅读(1446) | 评论(0) | 转发(0) |