shell脚本04

我们经常用的编辑器都有哪些?特点是什么?
emacs vi vim nano ... txt doc 


sed   <行编辑器>流编辑器
      1、通过非交互式来修改文本中的内容.默认情况下,不会直接修改原文件,而是所有的输出行都被打印到屏幕。逐行处理文件,并将结果发送到屏幕。
      2、sed 用来把文档或字符串里面的文字经过一系列编辑命令转换为另一种格式输出。
      3、sed 通常用来匹配一个或多个正则表达式的文本进行处理。
 




sed常见的语法模式有两种,一种叫命令行模式,另一种叫脚本模式。


命令行模式:
格式 
  sed 选项  '命令清单[地址定位]' files
  说明:引用shell script中的变量应使用双引号,而非通常使用的单引号
选项 :
-e 进行多项编辑,即对输入行应用多条sed命令时使用
-n 取消默认的输出
-f 指定sed脚本的文件名
-r  使用扩展正则表达式
-i 重定向输出<修改源文件>


命令:
a\ 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行
c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行


d 删除行
p 打印行
r 从文件中读取输入行
! 对所选行以外的所有行应用命令
s 用一个字符串替换另一个
g 在行内进行全局替换
w 将所选的行写入文件
y 将字符替换为另一字符(不能对正则表达式使用y命令)tr命令
&   保存查找串以便在替换串中引用
=   打印行号


定址:
定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。


x   指定x行号
x,y 指定x到y行号
/key/ 查询包含关键字的行
/key1/,/key2/   匹配包含两个关键字之间的行
/key/,x  从匹配关键字的行开始到第x行之间的行(包含关键字所在行)
x,/key/  从第x行开始到与关键字的匹配行之间的行
x,y! 不包含x到y行


注意:与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式。
示例:
1、p命令  打印
选项-n取消sed默认的打印,p命令把匹配模式root的行打印一遍。
2、d命令 删除
 1048  sed '1p' passwd 
 1049  sed -n '1p' passwd 
 1050  sed -n '5p' passwd 
 1051  sed -n '1,5p' passwd 
 1052  cat -n passwd 
 1053  sed -n '1,49!p' passwd 
 1054  sed -n '$p' passwd 
 1055  sed -n '^p' passwd 
 1056  sed '10d' passwd 
 1057  sed -n '10d' passwd 
 1058  sed -n '10dp' passwd 
 1059  sed  '1,40d' passwd 
 1060  sed  '$d' passwd 


3、s命令 搜索替换
 1066  sed -n '33s/\/sbin\/nologin/uplooking/p' passwd 
 1067  sed -n '33s#/sbin/nologin#uplooking#p' passwd 
g表示全局替换


自定义分隔符
# sed -n '1,5s/nologin$/hello/p' /etc/passwd
处理1到5行里匹配以nologin结尾的行,将行内所有nologin替换成hello
# cat -n /etc/passwd|tail -5|sed -n 's#/bin/bash#/sbin/nologin#gp'
可以自定义分隔符,换行符和反斜杠除外


4、 r命令
# sed '/root/r /tmp/1.txt' /etc/passwd|head -15
在匹配到root行的下面读入1.txt文件内容;如果匹配到root不止一行,则每行下面都插入
 1070  sed -n '41r /etc/hosts' passwd 
 1071  sed '41r /etc/hosts' passwd 
 1072  sed '1,2r /etc/hosts' passwd 
 1073  sed '$r /etc/hosts' passwd


5、 w命令
# sed '/root/w 2.txt' /etc/passwd
将匹配到的包含root的行另存为2.txt文件
 1076  cat /tmp/abc.txt 
 1077  sed -n '/root/p' passwd 
 1078  sed -n '/root/w /tmp/aaa.txt' passwd 
 1079  cat /tmp/aaa.txt 
 1080  sed -n '10,15w /tmp/bbb.txt' passwd 
 1081  cat /tmp/bbb.txt 
 1082  sed '10,15w /tmp/ccc.txt' passwd 
 1083  cat /tmp/ccc.txt 
 1084  sed '10,15w /tmp/ccc.txt' passwd 
 1085  cat /tmp/ccc.txt 


6、 a\ (a)命令 在匹配行的后面插入
# sed '/^root/a\ hello world' /etc/passwd|head -5
如果要追加的内容超过一行,则每一行都必须以反斜线结束,最后一行除外。最后一行将以引号和文件名结束。


 1103  sed 'ahello' pass.txt 
 1104  sed '$ahello' pass.txt 
# sed '10a\
hello\
world\
uuuu' pass.txt
# sed '10a\hello\nworld' pass.txt




7、 i\ (i)命令 在匹配行的前面插入
1108  sed 'i hello world' pass.txt 
 1109  sed '$i hello world' pass.txt 
 1110  sed '$i hello\nworld' pass.txt 
 1111  sed '10,15i\
8888888\
9999999' passw.txt
 1112  sed '10,15i\
8888888\
9999999' pass.txt


8、 c\ 命令
将已有文本修改成新的文本。
 1115  sed '22,30c hello' pass.txt 
 1116  sed 'c hello' pass.txt 
 1117  sed '$c hello' pass.txt 
 1118  sed '30c hello' pass.txt 
 1119  sed '30c hello\nworld' pass.txt


$c($c\) 最后一行修改
# sed '$c\ hello world' /etc/passwd |tail -5


9、 y命令
该命令与UNIX/Linux中的tr命令类似,字符按照一对一的方式从左到右进行转换。
正则表达式元字符对y命令不起作用。与s命令的分隔符一样,斜线可以被替换成其它的字符。
# sed '39,41y/stu/STU/' /etc/passwd
# sed '39,41y/stu\:x/STU@%/' /etc/passwd


 1129  sed '27,30y/stu/STU/' pass.txt 
 1130  sed '27,30y/stu:x/STU%@/' pass.txt 
 1131  sed '27,30y/stu:x/STU@/' pass.txt 
 1132  sed '27,30y/stu:x/UTS%@/' pass.txt 




10、 -e 选项 多项编辑
-e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。
sed -ne '/root/=' pass.txt -ne '/root/p'


11、-i 选项  直接修改原文件
# sed -i 's/user/stu/'
# sed -i '1,39d' passwd
 1139  sed '10,16d' pass.txt 
 1140  sed -i '10,16d' pass.txt 
 1141  cat pass.txt 
 1142  sed -i '10,16d' pass.txt 




12、& 符号 保留查找字符串 
# sed -n 's/^root/#&/p' passwd   注释掉以root开头的行
# sed -r 's/^root|^stu/#&/' passwd  注释掉以root开头或者以stu开头的行
# sed -n -r 's/^root|^stu/#&/p' /etc/passwd
# sed -n '1,5s/^[a-z].*/#&/p' passwd  注释掉1~5行中以任意小写字母开头的行
# sed -n '1,5s/^/#/p' /etc/passwd  注释1~5行
或者
sed -n '1,5s/^/#/p' passwd 以空开头的加上#
sed -n '1,5s/^#//p' passwd 以#开头的替换成空
vim ——>ctrl+v——>I(行头插入)——>ESC


 1146  sed -n 's/^uu/#&/p' pass.txt 
 1147  sed -n 's/^uu/&#/p' pass.txt 
 1148  sed -n 's/^uu.*/&#/p' pass.txt 
 1149  vim pass.txt 
 1150  sed -n '1,5s/^/#&/p' pass.txt 
 1151  sed -i '1,5s/^/#&/p' pass.txt 


13、= 打印行号
# sed -n '/bash$/=' passwd    打印以bash结尾的行的行号






脚本模式 :       
用法:sed -f file1.sed  file
       建议使用   ./sed.sh filename
       脚本的第一行写上
       #!/bin/sed -f


脚本模式下需要注意以下几点。
1) 脚本文件是一个sed的命令行清单。
2) 在每行的末尾不能有任何空格、制表符(tab)或其它文本。
3) 如果在一行中有多个命令,应该用分号分隔。
4) 不需要且不可用引号保护命令
5) #号开头的行为注释


# cat passwd
stu3:x:509:512::/home/user3:/bin/bash
stu4:x:510:513::/home/user4:/bin/bash
stu5:x:511:514::/home/user5:/bin/bash


# cat sed.sh 
#!/bin/sed -f
2a\
******************
2,$s/stu/user/
$a\
we inster new line
s/^[a-z].*/#&/




sed和正则表达式综合运用总结:
1、正则表达式必须以”/“前后规范间隔
例如:sed '/root/d' file
例如:sed '/^root/d' file
2、如果匹配的是扩展正则表达式,需要使用-r选来扩展sed  grep -E|egrep 
1》打印ftp配置文件生效的行
            # sed -r  '/^#|^$/d'  /etc/vsftpd/vsftpd.conf
            # egrep -v '^#|^$' /etc/vsftpd/vsftpd.conf
2》去掉第10行所有的数字冒号和斜杠
        # sed -nr '10s/[0-9]|:|\///pg' /etc/passwd  
        # sed -n '10s/[0-9:/]//pg' passwd
        # sed -nr '10s/([0-9]|:|\/)//pg' /etc/passwd


   注意:         
在正则表达式中如果出现特殊字符(^$.*/[]),需要以前导 ”\“ 号做转义
例如:sed '/\$foo/p' file
3、逗号分隔符
例如:sed '5,7d' file  删除5到7行
例如:sed '/root/,/ftp/d' file
删除第一个匹配字符串"root"到第一个匹配字符串"ftp"的所有行本行不找 循环执行
                   sed -n '/^root/,/uucp/d' /etc/passwd                
4、组合方式
例如:sed '1,/foo/d' file 删除第一行到第一个匹配字符串"foo"的所有行
例如:sed '/foo/,+4d' file 删除从匹配字符串”foo“开始到其后四行为止的行
例如:sed '/foo/,~3d' file 删除从匹配字符串”foo“开始删除到3的倍数行
例如:sed '1~5d' file 从第一行开始删每五行删除一行
例如:sed -n '/foo\|bar/p' file 显示配置字符串"foo"或"bar"的行
  sed -n '/foo/,/bar/p' file          显示匹配从foo到bar的行
  sed '1~2d'  file              除奇数行
  sed '0-2d'   file            删除偶数行 sed '1~2!d'  file
5、特殊情况
例如:sed '$d' file --删除最后一行
             sed '1d' file                删除第一行

正则表达式的操作:
sed 's/.//' a.txt --删除每一行中的第一个字符
sed 's/.//2' a.txt --删除每一行中的第二个字符
sed 's/.$//' a.txt --删除每一行中的最后一个字符






课堂练习:
1、打印匹配将任意数字替换成空或者制表符
 1171  sed -n 's/[0-9]//gp' pass.txt 
 1172  sed -n 's/[0-9]/\t/gp' pass.txt 
2、去掉文件1-5行中的数字、冒号、斜杠
 1175  sed -n '1,5s/[0-9:/]//gp' pass.txt 
 1176  sed -n '1,5s/[0-9:/ ]//gp' pass.txt 
 1177  sed -n '1,5s/[^a-Z]//gp' pass.txt 
 1178  sed -nr '1,5s/[0-9]|:|\///gp' pass.txt 
 1179  sed -nr '1,5s#[0-9]|:|/##gp' pass.txt
3、匹配root关键字的行替换成hello uplooking,并保存到test.txt文件中
 1187  sed '/root/chello uplooking' pass.txt |tee test.txt
 1189  sed -n '/root/chello uplooking' pass.txt |tee test.txt


4、删除vsftpd.conf、smb.conf、main.cf配置文件里所有注释的行及空行(不要直接修改原文件)
 1200  sed -e '/^#/d' -e '/^$/d' vsftpd.conf 
 1201  sed -r '/^#|^$/d' vsftpd.conf 
 1202  sed  '/^#/d;/^$/d' vsftpd.conf


 1206  sed -r '/^#|^;|^$|^\t$/d' smb.conf 
 1208  sed '/^#/d;/^$/d;/^;/d;/^\t$/d' smb.conf


5、使用sed命令截取自己的ip地址
# ifconfig eth0|sed -n 's#.*addr:\(.*\)Bcast.*#\1#p'


6、使用sed命令一次性截取ip地址、广播地址、子网掩码
# ifconfig eth0|sed -n 's#.*addr:\(.*\)Bcast:\(.*\)Mask:\(.*\)#ip地址是:\1\n广播地址是:\2\n子网掩码是:\3#p'


7、注释掉文件的2-3行和匹配到以root开头或者以ftp开头的行
# sed -ne '2,3s/^/#/p' pass.txt -nre 's/^root|^mail/#&/p'




sed [option] 'command|地址' filename
-n  p
-e
-r
-i


a(a\)
i(i\)
c(c\)  s/xxx/xxx/
y tr
r
w
d
$a $i $c  $p $d


x,y!
/key1/,x
/key1/,/key2/


sed -n '/root/p' file
sed -n '/root/s/bash$/uplooking/p' file


vim 1.sed
#!/bin/sed
i
a
...




sed -f 1.sed filename
vim 2.sed
#!/bin/sed -f
i
a
...


chmod +x 2.sed
./2.sed filename






作业1:
1、写一个初始化系统的脚本
1)自动修改主机名(如:ip是192.168.0.88,则主机名改为server88.uplook.com)
2)自动配置可用的yum源
3)自动关闭防火墙和selinux
作业2:
1、写一个搭建ftp服务的脚本,要求如下:
1) 不支持本地用户登录
2) 匿名用户可以上传 新建 删除

3) 匿名用户限速500KBps




#!/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.uplook.com
sed -i "/HOSTNAME/c\HOSTNAME=server$iptail.uplook.com" /etc/sysconfig/network
echo "$ipaddr server$iptail.uplook.com" >>/etc/hosts
#关闭防火墙和selinux
service iptables stop
setenforce 0 >/dev/null 2>&1
sed -i '/SELINUX=/c\SELINUX=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 < 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 "上传文件成功"

















你可能感兴趣的:(shell,shell,脚本)