SB:x:3:4:adm:/var/adm:/sbin/nologin
flag(修饰符) 实现增强功能模块的,默认情况只会替换每行首个匹配的内容
g 全局替换,行中所有被匹配的都会被替换
i 不区分字符大小写
p 打印模式空间的内容,请注意通常与sed命令选项-n配合使用只打印处理行
w file 将模式空间行打印写到file中
N 每行中被模式匹配的第N个内容被替换
l命令类似p命令,不过会显示控制字符,这个命令和vim的list命令相似,例如:
[root@BAIYU_110 tmp]# echo "column1 column2 column3" | sed 'l'
column1 column2 column3$
column1 column2 column3
[root@BAIYU_110 tmp]# echo "column1 column2 column3" | sed '='
1
column1 column2 column3
[root@BAIYU_110 tmp]# echo "column1 column2 column3" | sed 'p'
column1 column2 column3
column1 column2 column3
[root@BAIYU_110 tmp]# echo "column1 column2 column3" | sed 'l'
column1 column2 column3$
column1 column2 column3
如果flags中明确指定替换第n次的匹配,例如N=2:
[root@Note3 src]# echo "column1 column2 column3 column4" | sed 's/ /;/2'
column1 column2;column3 column4
当替换命令的pattern与地址部分是一样的时候,比如/regexp/s/regexp/replacement/可以省略替换命令中的pattern部分,这在单个编辑命令的情况下没多大用处,但是在组合命令的场景下还是能省不少功夫的
例如:把文中aa都加上s然后在有aa的行的行首再加上+
[root@Note3 src]# cat aa.txt
aa bb cc
da adsa casdfa
dasd dasf aa
bb cc nihao
[root@Note3 src]# sed '/aa/ s//aas/g;s/^/+/' aa.txt
+aas bb cc
+da adsa casdfa
+dasd dasf aas
+bb cc nihao
[root@Note3 src]# sed '/aa/ {s//aas/g;s/^/+/'} aa.txt
+aas bb cc
da adsa casdfa
+dasd dasf aas
bb cc nihao
[root@Note3 src]# sed -e '/aa/ s//aas/g' -e '/aa/ s/^/+/' aa.txt
+aas bb cc
da adsa casdfa
+dasd dasf aas
bb cc nihao 转换命令: y
语法:
[address]y/SET1/SET2/ 它的作用是在匹配的行上,将SET1中出现的字符替换成SET2中对应位置的字符,
例如1,3y/abc/xyz/会将1到3行中出现的a替换成x,b替换成y,c替换成z。是不是觉得这个功能很熟悉,其实这一点和tr命令是一样的。可以通过y命令将小写字符替换成大写字符,不过命令比较长:
$ echo "hello, world" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'HELLO, WORLD 使用tr命令来转换成大写:
$ echo "hello, world" | tr a-z A-Z HELLO, WORLD 取下一行命令: n
语法:
[address]n n命令为将下一行的内容提前读入,并且将之前读入的行(在模式空间中的行)输出到屏幕,然后后续的命令会应用到新读入的行上。因此n命令也会同d命令一样改变sed的控制流程。
书中给出了一个例子来介绍n的用法,假设有这么一个文本:
$ cat text .H1 "On Egypt"
Napoleon, pointing to the Pyramids, said to his troops:
"Soldiers, forty centuries have their eyes upon you."
现在要将.H1后面的空行删除:
$ sed '/.H1/{n;/^$/d}' text .H1"On Egypt"
Napoleon, pointing to the Pyramids, said to his troops:
"Soldiers, forty centuries have their eyes upon you."
退出命令: q
语法
[line-address]q #不能使用addr1,addr2,只能使用某行,读取到该行就退出 当sed读取到匹配的行之后即退出,不会再读入新的行,并且将当前模式空间的内容输出到屏幕。
例如打印前3行内容:
[root@BAIYU_110 tmp]# cat test
aa bb cc
da adsa casdfa
dasd dasf aa
bb cc nihao
[root@BAIYU_110 tmp]# sed '3q' test
aa bb cc
da adsa casdfa
dasd dasf aa
[root@BAIYU_110 tmp]# sed -n '3p' test
dasd dasf aa
[root@BAIYU_110 tmp]# sed -n '1,3p' test
aa bb cc
da adsa casdfa
dasd dasf aa
打印前3行也可以用p命令:但是对于大文件来说,前者比后者效率更高,因为前者读取到第N行之后就退出了。后者虽然打印了前N行,但是后续的行还是要继续读入,只不会不作处理。
到此为止,sed基础命令的部分就介绍完了。 示例(需要注意的细节):
1、让我们来看一个非常简单的例子,将一段文本中的pig替换成cow,并且将cow替换成horse:
[root@BAIYU_110 tmp]# echo "pig a cow"|sed 's/pig/cow/g;s/cow/hores/g'
hores a hores
初看起来好像没有问题,但是实际上是错误的,原因是第一个替换命令将所有的pig都替换成cow,紧接着的替换命令是基于前一个结果处理的,将所有的cow都替换成horse,造成的结果是全部的pig/cow都被替换成了horse,这样违背了我们的初衷。
在这种情况下,只需要调换下两个编辑命令的顺序:
# echo "ping a cow"|sed 's/cow/hoers/;s/ping/cow/'
2、分析下面2个命令的执行结果,为什么会是这样?
seq 6|sed '1,2d'|sed '1,2d'
seq 6|sed -e '1,2d' -e '1,2d'
第一眼觉得结果都是5,6
想了下第一个结果是5,6,第2个结果是3,4,5,6
不猜了,在电脑上分别执行一下这2个命令,出人意料
解释:
首先第一行被读入,遇到第一组expression -> 1, 2d,第一行匹配成功(打开匹配开关),执行d命令,d命令清空模式空间的内容,因此不会再执行接下来的命令。
继续从标准输入读入第二行,同第一行,读入第三行,第一组expression匹配失败(因为3>2),因此试着执行第二组expersson->1,2d,因为3>1,打开匹配开关,执行d。(这里是关键)
读入第四行,执行第二组expersson->1,2d,因为4>2,匹配失败,关闭匹配开关,同时也不执行d。
因此,最后第1 2 3行被删除。
练习:
He like his liker
He like his lover
she love her liker
she love her lover
1、删除以上内容当中包含“l..e”前后一致的行
# sed "/\(l..e\).\+\1/d"
2、将文件中“l..e”前后一致的行中,最后一个"1..e"词首的l换成大写L
# sed "/\(l..e\).\+\1/ s/l\(..er\)/L\1/"
# sed "/\(l..e\).\+\1/ s/l\(..er\)/L\1/p" #替换时修饰符的位置还可以用p和w,打印或保存更改后的内容
# sed "/\(l..e\).\+\1/ s/l\(..er\)/L\1/w /tmp/22222"
3、替换/etc/inittab文件中"id:3:initdefault:"-行中的数字为5
# sed "s/\(id\):[0-9]:\(initdefault:\)/\1:5:\2/p"
4、去取一个文件路径的目录名称,如/etc/sysconfig/network其目录为/etc/sysconfig,功能同dirname
# echo "/etc/sysconfig/network"|sed 's@/[^/]\+/\?$@@' #不知道为什么这里用""号就会报错,以后记得尽量用'号了,单引号更通用(当然‘’内不使用变量)