天天看點

Linux叢集和自動化維2.4.2 sed的用法示例

<b>2.4.2 sed的用法示例 </b>      

1. sed的基礎用法

1)删除行首空格,有下面幾種方法,代碼分别如下所示:

sed 's/^[ ]*//g'

filename

sed 's/^ *//g'

sed

's/^[[:space:]]*//g' filename

2)在行後和行前添加新行。

行後的添加指令如下所示:

's/pattern/&amp;\n/g' filename

行前的添加指令如下所示:

's/pattern/\n&amp;/g' filename

其中,&amp;代表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" ]

&amp;&amp; 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 &amp;&gt;

/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 ] &amp;&amp; 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 ] &amp;&amp; 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 &amp;&gt; /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的基本使用方法。

繼續閱讀