Chinaunix首页 | 论坛 | 博客
  • 博客访问: 53300
  • 博文数量: 15
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 195
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-11 13:32
文章分类

全部博文(15)

文章存档

2016年(4)

2015年(11)

我的朋友

分类: LINUX

2016-03-26 15:34:32

sed是一种语言


编辑文件通常用vim,vim是一种屏幕编辑器,只有打开才能编辑,必须交互,vim打开大文件时
vim会打开整个文件,有可能导致溢出。sed是一行一行处理,不会出现内存溢出。


sed工作流程:sed读取一行,在内存里执行某个操作,然后输出到屏幕


模式空间:sed读取一行到内存,这片内存被称为模式空间。(在模式空间里执行命令)


命令(操作):在模式空间执行的动作


语法:sed '范围(或条件) 命令' file 


[1].d:删除命令  sed 'd' passwd (读取一行删除一行然后输出到屏幕,所以无输出)
cat -n passwd|sed '20d'  删除第20行,20表示范围/条件
cat -n passwd|sed '12,18d'  删除第12到18行

范围里面的变量   :$表示最后一行
~表示跨步 
sed  '1 ~2d' passwd(从1开始,跨两步执行)

有时候条件并不一定是行号,可以使用正则表达式

正则表达式必须使用 //
:sed '/tom/d'  aa (删除aa中含有tom的行)
sed '/\btom\b/'  aa(删除含有tom这个单词的行)


[2].s:替换   s/old/new/标签
sed 's/tom/TOM/' aa  将tom替换为TOM,但是只替换每行第一个
sed   's/tom/TOM/2' aa  只替换每行第二个
sed   's/tom/TOM/g'  aa  全局替换
sed  '2,5s/tom/TOM/g'  aa 在范围内全局替换


-n关闭默认的输出
sed -n '2,5s/tom/TOM/g' aa  -n关闭了输出
sed -n '2,5s/tom/TOM/gp' aa   -n关闭了默认输出,但p标签将匹配的行打印出来

使用正则进行替换:
sed 's/[tT][oO][Mm]/TOM/g' aa


使用变量:在shell中定义aa=`hostname`
sed -n 's/#ServerName '$aa'/p'
使用shell中变量要用''

如何将passwd中所有的/sbin/nolog换成/bin/bash?
sed 's/\/sbin\/nologin/\/bin\/bash/' passwd

可以用###代替///,可以用任意字符替代
sed 's#/sbin/nologin#/bin/bash#' passwd


连续执行多个任务,用{}包含,命令之间用;隔开
sed '1{s/tom/TOM/gp; s/aaa/AAA/gp}' aa


使用-e进行多个命令
sed -e 's/tom/TOM/g' -e 's/TOM/tom/g' bb


替换s/old/new/
old可以使用正则,但new不能使用正则,但可以包含几个特殊符号

&:表示old的值
\U:把\U后面的字符全部换成大写
\u:把\u后面第一个字符换成大写
\L:把\L后面的字符全部换成小写
\l:把\u后面第一个字符换成小写
\E:表示中止(解决U和u之间的极端),遇到E就中止U的替换

面向的需求:把[]中的字符替换为大写的字符    sed 's/\[.*\]/\U&/' file
(中括号有特殊意义,必须转义)
正则中的.表示一个字符。类似通配符中的?
sed 's/^t../XXX/' aa  将t开头的三个字符替换成XXX


分组(group):在old部分相关位置使用(),在new中可以引用

去掉注释: sed 's/#\(ServerName\)/\1/p' file
括号有特殊意义,必须转义
第一个括号引用的内容用  \1代替,第二个用\2

a:在指定行的下一行添加一行
i:在指定行的上一行添加一行
c:满足某个条件的整行替换(和s不同)

sed '/^ONBOOT/c ONBOOT=yes' ifcfg-eth0

sed '$ a DNS=192.168.1.1',在最后一行添加一行DNS
sed '2 a DNS=192.168.1.1',在第二行添加一行DNS


y:替换
y/abc/XYZ/     对应替换,凡碰到a换成X,b换成Y,c换成Z

所有的操作均未改变原文件,如果要修改原文件 sed -i执行写入
如果写错了,如何恢复,最好要备份    sed -i.bak  (生成一个备份文件)
如果要写入文件,不要用-n和p标签,除非特殊情况


= 显示行号
n 读取下一行(区别-n) sed -n '1{n;p}' ifcfg-eth0  先读第一行,n读取下一行
并覆盖模式空间内容,再打印
再次读取时直接读取第三行
N 追加,也是读取下一行,但是,不会覆盖模式空间内容,而是追加进去,此时模式空间
有两行,而不是合并成一行,此时^
是这两行的开头,$是两行的结尾。

需求:文本 如下 
-----------------------------------------
rhce rhce rh
ce rhce rhce 
rhce
 
-------------------------------------------
如何将rhce全部替换成rhca?




保持空间:类似于一个仓库,临时存放数据
模式空间: 类似于一个车间,用于操作数据


x:让保持空间和模式空间的数据进行互换


假设有文件cc,内容如下
----------------------------------------
tom
jingli
bob
zongjian
mary
jingli
jerry
zongjian
----------------------------------------
显示职务为经理的人名(方法1):sed -n -e '{x;n}' -e '/jingli/{x;p}' cc




h:让模式空间的内容覆盖保持空间的值(模式空间不变)
显示职务为经理的人名(方法2):sed -n -e '/jingli/!h' -e '/jingli/{x;p}' cc
H:让模式空间的内容追加到保持空间去(模式空间不变)


显示职务为经理的人名和职务:sed -n -e '/jingli/!h' -e '/jingli/{H;x;p}' cc
sed -n -e '/jingli/!h' -e '/jingli/{H;x;s/\n/:/;p}' cc


g:保持空间内容覆盖写入模式空间
G:保持空间内容追加写入模式空间


要求职位和用户名互换位置:sed -n '{h;n;G;p}' cc
只打印用户名:sed -n '{h;n;g;p}' cc




sed没有自带循环,可以使用标签功能


sed ':标签 范围 1;命令1; /模式/b 标签名' file
sed ':lablex s/rhce/RHCE/; /rhce/b labelx' dd
定义一个lablex,进行替换命令,当碰到rhce时重复执行labelx内容

sed ':标签 范围 1;命令1; /模式/t 标签名' file







阅读(1644) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~