sed简介
- sed英文全称是stream editor。由贝尔实验室开发,如今主流Unix/Linux操作系统上都集成了这个工具。sed由自由软件基金组织(FSF)开发和维护,并且随着GNU/Linux进行分发,通常它也称作 GNU sed。
- 用来操作纯 ASCII 码的文本,处理时,把当前处理的行存储在临时缓冲区中,称为模式空间 (pattern space) 可以指定仅仅处理哪些行,sed 符合模式条件的处理,不符合条件的不予处理,处理完成之后把缓冲区的内容送往屏幕,接着处理下一行 ,这样不断重复,直到文件末尾。
模式空间与保持空间
- sed之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“保持空间(hold space)这2个空间的使用。
- 模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理,用于处理文本行。
- 保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域,用于保留文本行,是保存已经处理过的输入行,默认有一个空行。
- 注意:暂存空间里默认存储一个空行。
查看帮助信息
- 命令:
sed --help
可以看到常用参数的含义 - 命令:
man sed
查看具体的说明手册
sed 命令格式
调用 sed 命令有两种形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
常用选项
-n | 取消默认的输出,使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 |
---|---|
-e | 进行多项编辑,即对输入行应用多条sed命令时使用,直接在指令列模式上进行 sed 的动作编辑。 |
-f | 指定sed脚本的文件名. 直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作。 |
-r | sed 的动作支援的是延伸型正则表达式的语法。(预设是基础正则表达式语法) |
-i | 直接修改读取的文件内容,而不是由屏幕输出 |
sed 对字符的处理
模式 | 含义 |
---|---|
p | 显示,通常 p 会与参数 sed -n 一起用,即将某个选择的资料印出。 |
d | 删除,因为是删除,所以 d 后面通常不接任何内容 |
a | 添加, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行) |
c | 替换,c的后面可以接字串,这些字串可以取代 n1,n2 之间的行 |
w | 写入 |
i | 插入,i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行) |
s | 取代,可以直接进行替换的工作。通常这个 s 的动作可以搭配正则表达式。 |
p模式操作
cp /etc/fstab /mnt
cat -n fstab 显示文件内容,包括空行
cat -n fstab | sed 5p 非静默模式,第5行显示两次,且全文件内容都显示
cat -n fstab | sed -n 5p 静默模式只显示第五行
cat -n fstab | sed -n 3,5p 3,4,5行
cat -n fstab | sed -n '3p;5p' 3,5行
举例:
sed -n '/#/p' fstab 有#的行
sed -n '/#/!p' fstab 没有#的行
sed -n '/^$/!p' fstab 不是空行的行
sed -n '/^$/!p' fstab | sed -n '/^#/!p' 没有空行且没有#
sed -n 4p fstab 第四行
sed -n '4p;6p' fstab 4,6行
sed -n '4,6p' fstab 4-6行
举例:
测试题
建立用户,要求在执行脚本时,文件里的用户都会被建立出来。
先来学习两个循环:
1.
#!/bin/bash
for i in {1..10}
do
echo $i
done
2.
#!/bin/bash
for i in `seq 1 10`
do
echo $i
done
第一个版本:
人名文件:
vim userfile
user1
user2
user3
user4
user5
创建脚本:
vim create.sh
#!/bin/bash
[ -z "$1" ] && {
echo "Error:Please input userfile following script!!"
exit
}
[ -e "$1" ] || {
echo "$1 is not exist"
exit
}
Max_Num=`wc -l $1 | cut -d " " -f 1`
for Line_Num in `seq 1 $Max_Num`
do
USERNAME=`sed -n ${Line_Num}p $1`
useradd $USERNAME
done
这种方法在创建用户时不会有用户已经存在的提示。
执行结果:
第二个版本:
会判断用户是否已经存在。
#!/bin/bash
[ -z "$1" ] && {
echo "Error:Please input userfile following script!!"
exit
}
[ -e "$1" ] || {
echo "$1 is not exist"
exit
}
Max_Num=`wc -l $1 | cut -d " " -f 1`
for Line_Num in `seq 1 $Max_Num`
do
USERNAME=`sed -n ${Line_Num}p $1`
id $USERNAME &> /dev/null && {
echo $USERNAME is exist!
}||{
useradd $USERNAME
}
done
d模式操作
sed '/^#/d' fstab 删除有#的行
cat -n fstab | sed '5d' 删除第5行
cat -n fstab | sed '3,5d' 删除3-5行
cat -n fstab | sed '3d;5d' 删除第3,5行
sed '/^UUID/d' fstab 删除以UUID开头的行
a模式操作
sed '/^UUID/ahello westos' fstab 给uuid行后加hello westos
sed '/^UUID/ahello\nwestos' fstab 给uuid行后加hello westos 中间换行
i模式操作
sed '4ihello\nwestos' fstab 给第4行插入hello westos中间换行
sed '4ahello\nwestos' fstab 给第4行的后一行,也就是第5行插入
c模式操作
整行替换是c,单个字符是e
sed '/#/c"""""' fstab 把有#的行都替换为“”“”
sed '/#/cwestos' fstab 把有#的行都替换为westos
sed '/#/cwestos' -i fstab 把#替换为westos,并插入到文件fstab中,fstab必须存在
-i 插入文件中,文件内容直接改变
cat fstab
测试题
写一个脚本,直接修改http的端口
准备工作:
yum install httpd -y
systemctl start httpd
systemctl enable httpd
vim /etc/httpd/conf/httpd 主配置文件
修改端口命令为:sed '/^Listen/cListen 2222' -i /etc/httpd/conf/httpd.conf
脚本内容:
vim httpd.sh
#!/bin/bash
[ -z "$1" ] && {
echo "Error:Please input port following scripts!!"
exit
}
sed "/^Listen/cListen $1" -i /etc/httpd/conf/httpd.conf
systemctl restart httpd
注意:这里httpd可以重启成功是因为我的selinux是permissive状态,如果是enforing就有可能会报错重启失败。
w模式操作
>导入其他本件,文件可以不存在
-i 导入原文件,且文件必须存在,文件本身
6r 第六行
sed -n '/^UUID/w file' fstab 把fstab中UUID开头的行写入文件file中
cat file
cat -n fstab 查看 加数字 包括空行
cat -b fstab 不包括空行
sed '6r /mnt/file' fstab 把/mnt/file中的内容插入fstab的第6行后,也就是第7行开始
sed '$r /mnt/file' fstab 插入最后一行
cat file >> fstab 效果等于追加,但是追加直接改变了文件的内容
cat fstab
sed '$r/mnt/file' fstab -i test ##把/mnt/file的内容加到fstab最后一行,并把fstab的内容加到文件test中。这的前提是test必须存在
sed '$r/mnt/file' fstab > test ##test可以不存在
cat test
sed的其他用法
1.替换
cp /etc/passwd .
sed 's/sbin/westos/g' passwd 把所有的sbin换成westos
sed '1,5s/sbin/westos/g' passwd 把1--5行的sbin换成westos
sed '/lp/,/halt/s/sbin/westos/g' passwd 关键字,把lp到halt行的sbin换成westos
2.制定规则
cat rule
/^UUID/p
/UUID/=
sed -n -f rule fstab 制定规则
3.进行多项编辑,即对输入行应用多条sed命令时使用,直接在指令列模式上进行 sed 的动作编辑。
sed -n '/^UUID/p' fstab
sed -n '/^UUID/p;/^UUID/=' fstab
sed -n -e '/^UUID/p;/^UUID/=' fstab
sed -n -e '/^UUID/p' -e '/^UUID/=' fstab
4.其他
sed 's/\///g' passwd 去掉所有的/
sed 's/\//#######/g' passwd 把所有的/换成#######
sed 's@/@#########@g' passwd @=/
sed 's@sbin@westos@g' passwd 把所有的sbin替换为westos
sed 's/sbin/even/g' passwd
sed 's@sbin@westos@g;s/nologin/lee/g' passwd sbin替换为westos,nologin替换为lee
sed -e 's@sbin@westos@g' -e 's/nologin/lee/g' passwd
sed '$=' fstab ##统计文件行数,并在最后一行的上一行显示行数
sed -n '$=' fstab ##只显示统计的行数
sed '$!G' fstab ##给每一行的上面都加一个空行
sed '=' fstab ##给每一行的上面加行号
sed '=' fstab | sed 'N;s/\n/ /g ##N预处理,提前加载当前行的下一行的内容,同时处理。这条命令是给每一行都加行号,同时取消换行
sed '=' fstab |sed 's/\n/ /g' ##没用N,所以并没有取消换行,后面的半句没有执行。