1、什么是sed。
linux用三大文本处理利器:grep,sed,awk。
Sed:stream editor,流编辑器
简单来说就是一个编辑器,但是和vim不同,vim是把一个文件打开编辑然后存盘,而sed是从文件中读取一行出来处理,一行一行的处理,所以称之为流。
2、如何使用sed。
在学习使用sed之前,必须先明白sed的几个概念。
sed的工作流程:sed到文件中读取一行文字到内存中,然后在按指定的规则来处理这一行文字,处理完之后再去读取下一行文字到内存,再出来,一直这样下去,每次操作对象都是单独的一行。其实sed可以操作多行,但是有点点复杂,我们这里只讨论一行的。
模式空间:sed每次加载一行文字到内存中操作,而这块操作空间就称为模式空间。
补充:sed默认是不更改源文件,而是把它读取到内存操作之后送的屏幕,不会保存到源文件中,除非指定-i选项。
sed的基本语法:sed [option] '[定位][操作]' 文件
简单实例:把/etc/inittab中的第3行到第15行删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# sed '3,15d' test.txt
1
# inittab is only used by upstart for the default runlevel.
2
#
16
#
17
# Default runlevel. The runlevels used are:
18
# 0 - halt (Do NOT set initdefault to this)
19
# 1 - Single user mode
20
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
21
# 3 - Full multiuser mode
22
# 4 - unused
23
# 5 - X11
24
# 6 - reboot (Do NOT set initdefault to this)
25
#
26
id
:3:initdefault:
|
为了方便观察,我在文件加了行号。
从上面的结果我们可以看出3-15行被删除了。
单引号中用两个内容,分别是定位和操作,这个实例中的定位就3,15,操作就是d。
sed中有哪些定位方式呢?
sed地址定界:
start_line,end_line: 例如1,7
start_line,/pattern/: 例如3,/^#/
/pattern/: 仅匹配被模式到的行;
地址定位是可以使用正则表达式的,正则表达式放着//之间,sed默认使用基本正则表达式。
sed的常用操作命令:
p: 打印
d: 删除
a \text:在符合条件的行后面添加指定的内容;在的添加的内容中间使用“\n”能够完成多行附加;
i \text:在符合条件的行前面添加指定的内容;在的添加的内容中间使用“\n”能够完成多行附加;
c \text: 将符合条件的行替换为指定的文本;
r /path/to/somefile: 在符合条件的位置读入指定的文件;
w /path/to/somefile: 将符合条件的行保存至指定文件中;
=: 显示匹配到的行的行号;
s/要查找的内容/替换为的内容/:
要查找的内容:可以使用正则模式
替换为的内容:不可以使用模式,但可以引用, &
和vim中一样,s后的三个标记符号可以使用任意字符,比如:s#old#new#
和vim的替换一样,最后一个标记符后个加选项:
i: 忽略大小写
g:全局替换
如:s#old#new#g
sed的常用选项:
sed默认是将加载到内存的内容处理了送到屏幕(d操作的例外)。
我们还可以给定一些选项,让它改变默认操作
-n: 静默模式,即不输出模式空间中的内容;
-e: 指定在一个sed命令中使用多个script,格式为-e 'script1' -e 'script2' ...
-i: 直接修改原文件;
-r: 支持使用扩展正则表达式元字符;
-f /path/to/sed_script: 从文件中读取处理脚本,并执行
3、练习
(1) 文件中有以下内容:
He like his liker.
He like his lover.
She love her liker.
She love her lover.
1)、删除上述内容中l..e前后一致的行;
1
2
3
|
# sed '/\(l..e\).*\1/d' t.txt
he like his lover.
she love her liker.
|
2)、将上述内容中l..e前后一致的后面的l改为大写L;
1
2
3
4
5
|
# sed '/\(l..e\).*\1r/s#l#L#2g' t.txt
he like his Liker.
he like his lover.
she love her liker.
she love her Lover.
|
(2)、删除/etc/grub.conf文件中行首的空白符;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# sed '/^[[:space:]]\{1,\}/s/^[[:space:]]\{1,\}//' grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/vg_livecd-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)
/grub/splash
.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel
/vmlinuz-2
.6.32-431.el6.x86_64 ro root=
/dev/mapper/vg_livecd-lv_root
rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_livecd
/lv_swap
rd_NO_MD rd_LVM_LV=vg_livecd
/lv_root
SYSFONT=latarcyrheb-sun16 crashkernel=128M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd
/initramfs-2
.6.32-431.el6.x86_64.img
|
(3)、删除/etc/inittab文件中开头的#号;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# sed '/^#/s/#//' inittab
inittab is only used by upstart
for
the default runlevel.
ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
System initialization is started by
/etc/init/rcS
.conf
Individual runlevels are started by
/etc/init/rc
.conf
Ctrl-Alt-Delete is handled by
/etc/init/control-alt-delete
.conf
Terminal gettys are handled by
/etc/init/tty
.conf and
/etc/init/serial
.conf,
with configuration
in
/etc/sysconfig/init
.
For information on how to write upstart event handlers, or how
upstart works, see init(5), init(8), and initctl(8).
Default runlevel. The runlevels used are:
0 - halt (Do NOT
set
initdefault to this)
1 - Single user mode
2 - Multiuser, without NFS (The same as 3,
if
you
do
not have networking)
3 - Full multiuser mode
4 - unused
5 - X11
6 - reboot (Do NOT
set
initdefault to this)
id
:3:initdefault:
|
附加练习题:
1、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符
1
|
# sed '/\(^#[[:space:]]\{1,\}\)/s/^#[[:space:]]*//' file
|
2、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#
1
|
# sed '/^[[:space:]]\{1,\}#/s/^[[:space:]]\{1,\}#//' file
|