一、简介
在shell脚本编写中,时常会用到对文件的相关操作,比如增加内容,修改内容,删除部分内容,查看部分内容等,但是上述举例的这些操作一般都是需要在文本编辑器中才能操作,常用的文本编辑器如:gedit、vim、nano等又是交互式文本编辑器,脚本无法自己独立完成,必须有人参与才可以完成。如果这样的话又违背了我们编写脚本的意愿(全部由机器来完成,减少人的工作压力,提升工作效率)。emm…如何才能让这些操作全部脚本自己就搞定,而不需要人的参与,而且又能按照我们的脚本预案来完成呢?
为了解决上述问题,linux为大家提供了一些命令,比如Perl、sed等命令,着重介绍一下sed命令。
二、sed命令
1、sed介绍
sed是linux中提供的一个外部命令,它是一个行(流)编辑器,非交互式的对文件内容进行增删改查的操作,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。它和文本编辑器有本质的区别。
区别是:
文本编辑器: 编辑对象是文件
行编辑器:编辑对象是文件中的行
也就是前者一次处理一个文本,而后者是一次处理一个文本中的一行。这个是我们应该弄清楚且必须牢记的,否者可能无法理解sed的运行原理和使用精髓。
sed数据处理原理:
2、sed语法
sed 命令语法:
sed [options] ‘{command}[flags]’ [filename]
命令选项:
-e script 将脚本中指定的命令添加到处理输入时执行的命令中 多条件,一行中要有多个操作 -f script 将文件中指定的命令添加到处理输入时执行的命令中 -n 抑制自动输出 -i 编辑文件内容 -i.bak 修改时同时创建.bak备份文件。 -r 使用扩展的正则表达式 ! 取反 (跟在模式条件后与shell有所区别) command 对文件干什么 sed常用内部命令 a 在匹配后面添加 i 在匹配前面添加 d 删除 s 查找替换 字符串 c 更改 y 转换 N D P p 打印 #flags 数字 表示新文本替换的模式 g: 表示用新文本替换现有文本的全部实例 p: 表示打印原始的内容 w filename: 将替换的结果写入文件
3,演示示例
先准备一个文件
(1)command演示
[root@CentOs shell]# vim data1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
a添加后面命令:
[root@CentOs shell]# sed 'a\hello,world' data
1 the quick brown fox jumps over the lazy dog.
hello,world
2 the quick brown fox jumps over the lazy dog.
hello,world
3 the quick brown fox jumps over the lazy dog.
hello,world
4 the quick brown fox jumps over the lazy dog.
hello,world
5 the quick brown fox jumps over the lazy dog.
hello,world
[root@CentOs shell]#
[root@CentOs shell]# sed '3a\hello,world' data (对第三行追加)
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
hello,world
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
[root@CentOs shell]# sed '2,4a\hello,world' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
hello,world
3 the quick brown fox jumps over the lazy dog.
hello,world
4 the quick brown fox jumps over the lazy dog.
hello,world
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
[root@CentOs shell]# sed '/3 the/a\hello,world' data (“//”是开启匹配模式,这个生产环境中常用!!!)
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
hello,world
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
i插入前面命令:
[root@CentOs shell]# sed '/3 the/i\hello,world' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
hello,world
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
d删除命令:
[root@CentOs shell]# sed '/3 the/d' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]# cp /usr/local/nginx/conf/nginx.conf .
[root@CentOs shell]# sed -r '/^#/d' nginx.conf (删除以#开头的行)
[root@CentOs shell]# sed -r '/(^#|#|^$)/d' nginx.conf (删除以#开头或者包含#或者空行的行)
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@CentOs shell]#
s替换命令:
[root@CentOs shell]# cat data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]# sed 's/dog/cat/' data (把dog替换成cat)
1 the quick brown fox jumps over the lazy cat.
2 the quick brown fox jumps over the lazy cat.
3 the quick brown fox jumps over the lazy cat.
4 the quick brown fox jumps over the lazy cat.
5 the quick brown fox jumps over the lazy cat.
[root@CentOs shell]#
[root@CentOs shell]# sed '/3 the/s/dog/cat/' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy cat.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
c更改命令
[root@CentOs shell]# sed '/3 the/c\hello world' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
hello world
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
[root@CentOs shell]# sed '2,4c\hello world' data(这个有点特殊,把2-4行删除,再添加)
1 the quick brown fox jumps over the lazy dog.
hello world
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
y转换命令:
[root@CentOs shell]# sed 'y/abcdefg/ABCDEFG/' data
1 thE quiCk Brown Fox jumps ovEr thE lAzy DoG.
2 thE quiCk Brown Fox jumps ovEr thE lAzy DoG.
3 thE quiCk Brown Fox jumps ovEr thE lAzy DoG.
4 thE quiCk Brown Fox jumps ovEr thE lAzy DoG.
5 thE quiCk Brown Fox jumps ovEr thE lAzy DoG.
[root@CentOs shell]#
p打印命令
[root@CentOs shell]# sed 'p' data (出现两行,是因为把内存和文件都打印了出来!!!)
1 the quick brown fox jumps over the lazy dog.
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
[root@CentOs shell]# sed '/3 the/p' data
1 the quick brown fox jumps over the lazy dog.
2 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
3 the quick brown fox jumps over the lazy dog.
4 the quick brown fox jumps over the lazy dog.
5 the quick brown fox jumps over the lazy dog.
[root@CentOs shell]#
(2)flags演示
数字:
[root@CentOs shell]# cat data
1 the quick brown fox jumps over the lazy dog.dog
2 the quick brown fox jumps over the lazy dog.dog
3 the quick brown fox jumps over the lazy dog.dog
4 the quick brown fox jumps over the lazy dog.dog
5 the quick brown fox jumps over the lazy dog.dog
[root@CentOs shell]# sed 's/dog/cat/' data
1 the quick brown fox jumps over the lazy cat.dog
2 the quick brown fox jumps over the lazy cat.dog
3 the quick brown fox jumps over the lazy cat.dog
4 the quick brown fox jumps over the lazy cat.dog
5 the quick brown fox jumps over the lazy cat.dog
[root@CentOs shell]# sed 's/dog/cat/2' data
1 the quick brown fox jumps over the lazy dog.cat
2 the quick brown fox jumps over the lazy dog.cat
3 the quick brown fox jumps over the lazy dog.cat
4 the quick brown fox jumps over the lazy dog.cat
5 the quick brown fox jumps over the lazy dog.cat
[root@CentOs shell]#
g:全部替换
[root@CentOs shell]# sed 's/dog/cat/g' data
1 the quick brown fox jumps over the lazy cat.cat
2 the quick brown fox jumps over the lazy cat.cat
3 the quick brown fox jumps over the lazy cat.cat
4 the quick brown fox jumps over the lazy cat.cat
5 the quick brown fox jumps over the lazy cat.cat
[root@CentOs shell]#
p:打印输出
[root@CentOs shell]# sed '3s/dog/cat/p' data
1 the quick brown fox jumps over the lazy dog.dog
2 the quick brown fox jumps over the lazy dog.dog
3 the quick brown fox jumps over the lazy cat.dog
3 the quick brown fox jumps over the lazy cat.dog
4 the quick brown fox jumps over the lazy dog.dog
5 the quick brown fox jumps over the lazy dog.dog
[root@CentOs shell]#
w filename:将替换的结果写入文件中
[root@CentOs shell]# sed '3s/dog/cat/w newfile data
1 the quick brown fox jumps over the lazy dog.dog
2 the quick brown fox jumps over the lazy dog.dog
3 the quick brown fox jumps over the lazy cat.dog
4 the quick brown fox jumps over the lazy dog.dog
5 the quick brown fox jumps over the lazy dog.dog
[root@CentOs shell]# ls
data ip.txt nginx.conf ShellTest.sh zzku.sh
fenjie.txt newfile NginxTestfailing.sh test01.sh
[root@CentOs shell]# cat newfile
3 the quick brown fox jumps over the lazy cat.dog
[root@CentOs shell]#
(3)命令选项
-n:只输入自己想要的那部分
[root@CentOs shell]# sed -n '3s/dog/cat/p' data
3 the quick brown fox jumps over the lazy cat.dog
[root@CentOs shell]#
-e:多条件,一行中要有多个操作
[root@CentOs shell]# sed -e 's/brown/grey/;s/dog/cat/' data
1 the quick grey fox jumps over the lazy cat.dog
2 the quick grey fox jumps over the lazy cat.dog
3 the quick grey fox jumps over the lazy cat.dog
4 the quick grey fox jumps over the lazy cat.dog
5 the quick grey fox jumps over the lazy cat.dog
[root@CentOs shell]#
-f:将文件中的命令添加到处理输入时执行的命令中
[root@CentOs shell]# vim file
[root@CentOs shell]# cat file
s/brown/grey/
s/dog/cat/
[root@CentOs shell]# sed -f file data
1 the quick grey fox jumps over the lazy cat.dog
2 the quick grey fox jumps over the lazy cat.dog
3 the quick grey fox jumps over the lazy cat.dog
4 the quick grey fox jumps over the lazy cat.dog
5 the quick grey fox jumps over the lazy cat.dog
[root@CentOs shell]#
-i:修改源文件(不可逆)
[root@CentOs shell]# sed -i 's/dog/cat/g' data
[root@CentOs shell]# cat data
1 the quick brown fox jumps over the lazy cat.cat
2 the quick brown fox jumps over the lazy cat.cat
3 the quick brown fox jumps over the lazy cat.cat
4 the quick brown fox jumps over the lazy cat.cat
5 the quick brown fox jumps over the lazy cat.cat
[root@CentOs shell]#
[root@CentOs shell]# sed -i.bak 's/cat/dog/g' data(使用-i时,可以备份一个文件)
[root@CentOs shell]# ls
data fenjie.txt ip.txt NginxTestfailing.sh test01.sh
data.bak file nginx.conf ShellTest.sh zzku.sh
[root@CentOs shell]# cat data.bak (源文件的备份还是没有变化)
1 the quick brown fox jumps over the lazy cat.cat
2 the quick brown fox jumps over the lazy cat.cat
3 the quick brown fox jumps over the lazy cat.cat
4 the quick brown fox jumps over the lazy cat.cat
5 the quick brown fox jumps over the lazy cat.cat
[root@CentOs shell]# cat data(源文件已被修改)
1 the quick brown fox jumps over the lazy dog.dog
2 the quick brown fox jumps over the lazy dog.dog
3 the quick brown fox jumps over the lazy dog.dog
4 the quick brown fox jumps over the lazy dog.dog
5 the quick brown fox jumps over the lazy dog.dog
[root@CentOs shell]#
-r:使用正则表达式
[root@CentOs shell]# sed -r -n '/^(root)(.*)(bash)$/p' /etc/passwd(打印以root开头、中间任意、结尾以bash结束的行)
root:x:0:0:root:/root:/bin/bash
[root@CentOs shell]#
!:取反
我们也不一定非得使用文件输出。以管道为例:
[root@CentOs shell]# echo "Tom is cool"|sed 's/Tom is/I am/'
I am cool
[root@CentOs shell]#
三、sed的一些小技巧
$=:统计行号
[root@CentOs shell]# sed -n '$=' data
5
[root@CentOs shell]#
=:给每一行加行号
[root@CentOs shell]# sed '=' data
1
1 the quick brown fox jumps over the lazy dog.dog
2
2 the quick brown fox jumps over the lazy dog.dog
3
3 the quick brown fox jumps over the lazy dog.dog
4
4 the quick brown fox jumps over the lazy dog.dog
5
5 the quick brown fox jumps over the lazy dog.dog
[root@CentOs shell]#
四、写一个搭建ftp服务的脚本
要求如下:
1)不支持本地用户登录 local_enable=NO
2) 匿名用户可以上传 新建 删除 anon_upload_enable=YES anon_mkdir_write_enable=YES
3) 匿名用户限速500KBps anon_max_rate=500000
仅供参考: #!/bin/bash ipaddr=`ifconfig eth0|sed -n '2p'|sed -e 's/.*inet addr:\(.*\) Bcast.*/\1/g'` iptail=`echo $ipaddr|cut -d'.' -f4` ipremote=192.168.1.10 #修改主机名 hostname server$iptail.zutuanxue.com sed -i "/HOSTNAME/cHOSTNAME=server$iptail.zutuanxue.com" /etc/sysconfig/network echo "$ipaddr server$iptail.zutuanxue.cc" >>/etc/hosts #关闭防火墙和selinux service iptables stop setenforce 0 >/dev/null 2>&1 sed -i '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config #配置yum源(一般是内网源) #test network ping -c 1 $ipremote > /dev/null 2>&1 if [ $? -ne 0 ];then echo "你的网络不通,请先检查你的网络" exit 1 else echo "网络ok." fi cat > /etc/yum.repos.d/server.repo << end [server] name=server baseurl=ftp://$ipremote enabled=1 gpgcheck=0 end #安装软件 read -p "请输入需要安装的软件,多个用空格隔开:" soft yum -y install $soft &>/dev/null #备份配置文件 conf=/etc/vsftpd/vsftpd.conf \cp $conf $conf.default #根据需求修改配置文件 sed -ir '/^#|^$/d' $conf sed -i '/local_enable/c\local_enable=NO' $conf sed -i '$a anon_upload_enable=YES' $conf sed -i '$a anon_mkdir_write_enable=YES' $conf sed -i '$a anon_other_write_enable=YES' $conf sed -i '$a anon_max_rate=512000' $conf #启动服务 service vsftpd restart &>/dev/null && echo"vsftpd服务启动成功" #测试验证 chmod 777 /var/ftp/pub cp /etc/hosts /var/ftp/pub #测试下载 cd /tmp lftp $ipaddr <<end cd pub get hosts exit end if [ -f /tmp/hosts ];then echo "匿名用户下载成功" rm -f /tmp/hosts else echo "匿名用户下载失败" fi #测试上传、创建目录、删除目录等 cd /tmp lftp $ipaddr << end cd pub mkdir test1 mkdir test2 put /etc/group rmdir test2 exit end if [ -d /var/ftp/pub/test1 ];then echo "创建目录成功" if [ ! -d /var/ftp/pub/test2 ];then echo "文件删除成功" fi else if [ -f /var/ftp/pub/group ];then echo "文件上传成功" else echo "上传、创建目录删除目录部ok" fi fi [ -f /var/ftp/pub/group ] && echo "上传文件成功"