<b>2.4.2 sed的用法示例 </b>
1. sed的基础用法
1)删除行首空格,有下面几种方法,代码分别如下所示:
sed 's/^[ ]*//g'
filename
sed 's/^ *//g'
sed
's/^[[:space:]]*//g' filename
2)在行后和行前添加新行。
行后的添加命令如下所示:
's/pattern/&\n/g' filename
行前的添加命令如下所示:
's/pattern/\n&/g' filename
其中,&代表pattern。
3)使用变量替换(使用双引号),代码如下:
sed -e
"s/$var1/$var2/g" filename
4)在第一行前插入文本,代码如下:
sed -i '1 i\插入字符串' filename
5)在最后一行插入字符串,代码如下:
sed -i '$ a\插入字符串' filename
6)在匹配行前插入字符串,代码如下:
sed -i
'/pattern/ i "插入字符串"' filename
7)在匹配行后插入字符串,代码如下:
'/pattern/ a "插入字符串"' filename
8)删除文本中的空行、以空格组成的行及#号注释的行,代码如下:
grep -v ^#
filename | sed /^[[:space:]]*$/d | sed /^$/d
9)将目录/modules下面所有文件中的zhangsan都修改成list(注意备份原文件),代码如下:
's/zhangsan/list/g' `grep zhangsan -rl /modules`
2.巧用vim+sed整理nginxd.txt脚本文件
笔者曾在工作中遇到过一个问题,需要使用nginx配置脚本来解决,但在复制到服务器中并运行时发现前面的001~100行都有行标识符,外带空格,影响运行和美观。本来想逐行删除的,后来觉得过于麻烦,于是想到了用sed来解决问题,解决方法如下。
1)先在 vim里删除所有行的首数字,命令如下所示:
:%s/^[0-9][0-9]*
//
2)然后删除所有行的首空字符,命令如下所示:
's/^[[:space:]]*//' nginxd.sh
整个nginxd.txt演示脚本如下,有兴趣的朋友也可以拿来练下手。
001 #!/bin/sh
002
003 # source function library
004 . /etc/rc.d/init.d/functions
005
006 # source networking configuration.
007 . /etc/sysconfig/network
008
009 # check that networking is up.
010 [ ${networking} = "no" ]
&& exit 0
011
012 retval=0
013 prog="nginx"
014
015 nginxdir=/usr/local/nginx
016 nginxd=$nginxdir/sbin/nginx
017 nginxconf=$nginxdir/conf/nginx.conf
018 nginxpid=$nginxdir/nginx.pid
019
020 nginx_check()
021 {
022 if [[ -e $nginxpid ]]; then
023 ps aux |grep -v grep |grep -q nginx
024 if (( $? == 0 )); then
025 echo "$prog already
running..."
026 exit 1
027 else
028 rm -rf $nginxpid &>
/dev/null
029 fi
030 fi
031 }
032
033 start()
034 {
035 nginx_check
036 if (( $? != 0 )); then
037 true
038 else
039 echo -n $"starting $prog:"
040 daemon $nginxd -c $nginxconf
041 retval=$?
042 echo
043 [ $retval = 0 ] && touch
/var/lock/subsys/nginx
044 return $retval
045 fi
046 }
047
048 stop()
049 {
050 echo -n $"stopping $prog:"
051 killproc $nginxd
052 retval=$?
053 echo
054 [ $retval = 0 ] && rm -f
/var/lock/subsys/nginx $nginxpid
055 }
056
057 reload()
058 {
059 echo -n $"reloading $prog:"
060 killproc $nginxd -hup
061 retval=$?
062 echo
063 }
064
065 monitor()
066 {
067 status $prog &> /dev/null
068 if (( $? == 0 )); then
069 retval=0
070 else
071 retval=7
072 fi
073 }
074
075 case "$1" in
076 start)
077 start
078 ;;
079 stop)
080 stop
081 ;;
082 restart)
083 stop
084 start
085 ;;
086 reload)
087 reload
088 ;;
089 status)
090 status $prog
091 retval=$?
092 ;;
093 monitor)
094 monitor
095 ;;
096 *)
097 echo $"usage: $0
{start|stop|restart|reload|status|monitor}"
098 retval=1
099 esac
100 exit $retva
脚本下载地址:https://github.com/yuhongchun/automation。
此文件还有很多变化,比如空格在开头,序列号在中间,也可以用sed来解决,不过应该写出怎样的sed命令来解决,就留给大家来思考吧!
3. sed结合正则表达式批量修改文件名
笔者曾在工作中遇到了更改文件的需求,原来某文件test.txt中的链接地址为:
http://www.5566.com/produce/2007080412/315613171.shtml
http://bz.5566.com/produce/20080808/311217.shtml
http://gz.5566.com/produce/20090909/311412.shtml
现要求将http://*.5566.com更改为/home/html/www.5566.com,于是用sed结合正则表达式来解决这个问题,命令如下所示:
's/http.*\.com/home\/html\/www.5566.com/g' test.txt
如果是用纯sed命令,方法更简单,如下所示:
's@http://[^.]*.5566.com@/home/html/www.5566.com@g' test.txt
sed是完全支持正则表达式的,在正则表达式里,[^.]表示为非.的所有字符,换成[^/]也可以;另外,@是sed的分隔符,我们也可以用其他符号,比如/,但是如果要用到/的话就得表示成\/了,所以笔者经常用的方法是采用@作为分隔符。
4.在配置.conf文件时,为相邻的几行添加#号
例如,我们要将test.txt文件中的31~36行加上#号,使这部分内容暂时失效,该如何实现呢?
在vim中,可以执行如下命令:
:31,36 s/^/#/
而使用sed执行更加方便,命令如下所示:
'31,36s/^/#/' test.txt
反之,如果要将31~36行带#号的全部删除,用sed又该如何实现呢?方法如下:
sed –i
‘31,36s/^#//’ test.txt
许多人习惯在这个方法后面带个g,事实上,如果没有g,则表示从行的左端开始匹配,每一行第一个与之匹配的都会被换掉;如果有g,则表示每一行所有与之匹配的都会被换掉。
5.利用sed分析日志
利用sed还可以很方便地分析日志。例如,在以下的secure日志文件中,想用sed抓取12:48:48至12:48:55的日志:
apr 17 05:01:20
localhost sshd[16375]: pam_unix(sshd:auth): authentication failure;
logname= uid=0 euid=0 tty=ssh ruser= rhost=222.186.37.226 user=root
apr 17 05:01:22
localhost sshd[16375]: failed password for root from 222.186.37.226 port 60700 ssh2
localhost sshd[16376]: received disconnect from 222.186.37.226: 11: bye bye
localhost sshd[16377]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
rhost=222.186.37.226 user=root
apr 17 05:01:24
localhost sshd[16377]: failed password for root from 222.186.37.226 port 60933 ssh2
localhost sshd[16378]: received disconnect from 222.186.37.226: 11:
bye bye
localhost sshd[16379]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
apr 17 05:01:26
localhost sshd[16379]: failed password for root from 22.186.37.226
port 32944 ssh2
localhost sshd[16380]: received disconnect from 222.186.37.226: 11:
apr 17 05:01:27
localhost sshd[16381]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
apr 17 05:01:29
localhost sshd[16381]: failed password for root from 222.186.37.226 port 33174 ssh2
localhost sshd[16382]: received disconnect from 222.186.37.226: 11:
localhost sshd[16383]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
apr 17 05:01:31
localhost sshd[16383]: failed password for root from 222.186.37.226 port 33474 ssh2
localhost sshd[16384]: received disconnect from 222.186.37.226: 11:
apr 17 05:01:32
localhost sshd[16385]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser=
可以利用sed截取日志命令,如下所示:
cat
/var/log/secure | sed -n '/12:48:48/,/12:48:55/p'
脚本显示结果如下所示:
apr 23 12:48:48
localhost sshd[20570]: accepted password for root from 220.249.72.138 port
27177 ssh2
localhost sshd[20570]: pam_unix(sshd:session): session opened for user root by (uid=0)
apr 23 12:48:55
localhost sshd[20601]: accepted password for root from 220.249.72.138 port
59754 ssh2
sed的用法还有许多,这就要靠大家在日常工作中归纳总结了。有兴趣的朋友还可以多了解下awk的用法,我们在工作中要频繁地分析日志文件,awk+sed是比较好的选择,下面介绍下awk的基本使用方法。