目录
1. 工作原理
sed是一种流编辑器,它是文本处理中非常有用的工具,能够完美的配合正则表达式使用,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变。
sed的特点:
(1)sed命令是将一系列的编辑命令应用于一批文本的理想工具。
(2)sed命令是一个非交互式的文本编辑器,它可以对来自文本文件以及标准输入的文本进行编辑。其中,标准输入可以是来自键盘、文件重定向、字符串、变量或者是管道的文本。
(3)sed命令会从文件或者标准输入中一次读取一行数据,将其复制到缓冲区(最多8192字节),然后读取命令行或者脚本的编辑子命令,对缓冲区中的文本行进行编辑。重复此过程,一直到所有的文本行都处理完毕。
2. sed基本语法
常用的选项:
-n,–quiet,–silent:不输出模式空间中的内容,使用安静模式,在一般sed的用法中,所有来自STDIN的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来;
-i:直接编辑原文件,而不是由屏幕输出,默认不对原文件进行操作;
-e:直接在命令行模式上进行sed的动作编辑,多个子命令之间也可以用分号隔开;
sed -e 'command1;command2... filename或者sed -e 'command1' -e 'command2' ……filename
-r:使用扩展正则表达式;
-f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作。
3. 模式空间中的编辑操作
3.1 地址定界
1)#:#为数字,指定要进行处理操作的行;1,表示第一行;
2)$:表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行;
3)/regexp/:表示能够被regexp匹配到的行; regexp即基于正则表达式的匹配;
4)/regexp/I:匹配时忽略大小写;
5)\%regexp%: 任何能够被regexp匹配到的行,换用%(用其他字符也可以,如:#)为边界符号;
6)addr1,addr2:指定范围内的所有的行(范围选定);
常用地址定界表示方式:
a)0,/regexp/:从起始行开始到第一次能够被regexp匹配到的行。
b)/regexp/,/regexp/:被模式匹配到的行内的所有的行。
7)first~step:指定起始的位置及步长,例如:1~2表示1,3,5…
8)addr1,+N:指定行以及以后的N行;
addr1,~N:指定行开始的N行;
注意事项:
1、如果没有指定地址,表示命令将应用于每一行
2、如果只有一个地址,表示命令将应用于这个地址匹配的所有行
3、如果指定了由逗号分隔的两个地址,表示命令应用于匹配第一个地址和第二地址之间的行(包括这两行)
4、如果地址后面跟有感叹号,表示命令将应用于不匹配该地址的所有行
3.2 常用编辑命令
1)d:删除匹配到的行
2)p:打印当前模式空间内容
3)a \text:append,表示在匹配到的行之后追加内容
4)i \text:insert,表示在匹配到的行之前追加内容
5)c \text:change,表示把匹配到的行和给定的文本进行交换
6)s/regexp/replacement/flages:查找替换,替换regexp匹配到的内容(其中/可以用其他字符代替,例如@)
其他编辑命令:
常用的flages:
g:全局替换,默认只替换第一个
i: 不区分大小写
p:如果成功替换则打印
7)r 读入文件内容追加到匹配行后面
8)R 读入文件一行内容追加到匹配行后面
9)y :y/source/dest/ 固定长度替换,要求替换的字符串长度相等
10)w /path/to/somefile:将匹配到的文件内容追加到指定的文件末尾
sed 's/north/hello/' datafile --替换每行第一个north
sed 's/north/hello/g' datafile --全部替换
sed '1 s/north/hello/g' datafile --替换第一行所有的north
sed '1 s/north/hello/' datafile --替换第一行第一个north
sed '1 s/north/hello/2' datafile --只替换第一行第二个north
4.sed扩展
特殊符号 | 说明 |
---|---|
! | 对指定行以外的所有行应用命令 |
= | 打印当前行行号 |
~ | “first~step”表示从first行开始,以步长step递增 |
& | 代表被替换的内容;实现一行命令语句可以执行多条sed命令 |
{} | 对单个地址或地址范围执行批量操作+地址范围中用到的符号,做加法运算 |
5.练习
5.1、删除grub2.conf文件中所有以空白开头的行行首的空白字符
[root@localhost ~]# sed -r 's#^[[:space:]]+##g' /etc/grub2.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -s $prefix/grubenv ]; then
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${saved_entry}"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
5.2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[root@localhost ~]# sed -r 's/^#[[:space:]]+//g' /etc/fstab
#
/etc/fstab
Created by anaconda on Wed Aug 31 11:53:19 2022
#
Accessible filesystems, by reference, are maintained under '/dev/disk/'.
See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
After editing this file, run 'systemctl daemon-reload' to update systemd
units generated from this file.
#
/dev/mapper/rhel-root / xfs defaults 0 0
UUID=17ccd2ae-9d1a-40bc-a7fd-721cf7e4ff54 /boot xfs defaults 0 0
/dev/mapper/rhel-swap none swap defaults 0 0
/dev/sr0 /mnt
[root@localhost ~]#
5.3、在/etc/fstab文件每一行行首增加#号
[root@localhost ~]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Aug 31 11:53:19 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/rhel-root / xfs defaults 0 0
UUID=17ccd2ae-9d1a-40bc-a7fd-721cf7e4ff54 /boot xfs defaults 0 0
/dev/mapper/rhel-swap none swap defaults 0 0
/dev/sr0 /mnt
[root@localhost ~]# sed 's/\(.*\)/#\1/' /etc/fstab
#
##
## /etc/fstab
## Created by anaconda on Wed Aug 31 11:53:19 2022
##
## Accessible filesystems, by reference, are maintained under '/dev/disk/'.
## See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
##
## After editing this file, run 'systemctl daemon-reload' to update systemd
## units generated from this file.
##
#/dev/mapper/rhel-root / xfs defaults 0 0
#UUID=17ccd2ae-9d1a-40bc-a7fd-721cf7e4ff54 /boot xfs defaults 0 0
#/dev/mapper/rhel-swap none swap defaults 0 0
#/dev/sr0 /mnt
[root@localhost ~]#
5.4、在/etc/fstab文件中不以#开头的行的行首增加#号
[root@localhost ~]# sed 's/^\([^#].*\)/#\1/' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Wed Aug 31 11:53:19 2022
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
#/dev/mapper/rhel-root / xfs defaults 0 0
#UUID=17ccd2ae-9d1a-40bc-a7fd-721cf7e4ff54 /boot xfs defaults 0 0
#/dev/mapper/rhel-swap none swap defaults 0 0
#/dev/sr0 /mnt
[root@localhost ~]#
5.5、利用sed取出ifconfig命令中本机的IPv4地址
# 方法1
[root@localhost ~]# ifconfig|sed -n '2p'|sed 's/.*inet[[:space:]]*//'|sed 's/[[:space:]]*netmask.*//'
172.25.10.130
# 方法二
[root@localhost ~]# ifconfig|sed -n '2p'|sed -r 's/.*net //g'|sed -r 's/ net.*//g'
172.25.10.130
# 方法三
[root@localhost ~]# ifconfig |sed -nr '2s#^.*net (.*) netm.*$#\1#gp'
172.25.10.130
[root@localhost ~]#
5.6、关闭本机SELinux的功能
[root@localhost ~]# sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config
5.7、在/etc/hosts配置文件中添加内容
172.25.10.130 host
[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost ~]# sed -i '$a 172.25.10.130 host' /etc/hosts
[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.10.130 host
[root@localhost ~]#