文字三劍客之sed的用法

上善若水~小輝發表於2020-09-06

第1章            Sed命令

1.1  sed 命令執行過程

 

 1.2  sed介紹

sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行儲存在臨時緩衝區中,稱為“模式空間”(pattern space),接著用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往螢幕。然後讀入下行,執行下一個迴圈。如果沒有使諸如‘D’的特殊命令,那會在兩個迴圈之間清空模式空間,但不會清空保留空間。這樣不斷重複,直到檔案末尾。檔案內容並沒有改變,除非你使用重定向儲存輸出或者-i進行修改。

1.3  sed功能

功能:主要用來自動編輯一個或多個檔案,簡化對檔案的反覆操作,編寫轉換程式等
參考:http://www.gnu.org/software/sed/manual/sed.html

1.4 sed用法

sed[option]... 'script' inputfile...
常用選項:
-n:不輸出模式空間內容到螢幕,即不自動列印
-e:多點編輯
-f: /PATH/SCRIPT_FILE從指定檔案中讀取編輯指令碼
-r:支援使用擴充套件正規表示式
-i:直接將處理的結果寫入檔案
-i.bak:備份檔案並原處編輯

script:'地址命令'

地址定界:
(1) 不給地址:對全文進行處理

(2) 單地址:

    #: 指定的行,$:最後一行
    /pattern/:被此處模式所能夠匹配到的每一行

(3) 地址範圍:

    #,#
    #,+#
    /pat1/,/pat2/
    #,/pat1/

(4) ~:步進

    1~2 奇數行
    2~2 偶數行

編輯命令command

d: 刪除模式空間匹配的行,並立即啟用下一輪迴圈
p: 列印當前模式空間內容,追加到預設輸出之後
a: [\]text在指定行後面追加文字,支援使用\n實現多行追加
i: [\]text在行前面插入文字
c: [\]text替換行為單行或多行文字
w: /path/file儲存模式匹配的行至指定檔案
r: /path/file讀取指定檔案的文字至模式空間中匹配到的行後
=: 為模式空間中的行列印行號
!: 模式空間中匹配行取反處理

查詢替換

s///    查詢替換,支援使用其它分隔符,s@@@,s###

替換標記:

     g:行內全域性替換
     p:顯示替換成功的行
     w:/PATH/FILE將替換成功的行儲存至檔案中
        sed命令的指示資訊
        p   print  輸出資訊
        i   insert 輸入資訊,在指定資訊前面插入新的資訊
        a   append 附加資訊,在指定資訊後面附加新的資訊                    
        d   delete 刪除指定資訊
        s   substitute 替換資訊 s###g(全域性替換)
        c   替換修改指定的一整行資訊   
 

   使用sed查詢檔案的行

              1 行號 3p                                                 # p  print 列印輸出

              2 連續的行號 3,5p                                   # 輸出第3行到第5行 ,表示序列

              3 過濾找出包含xxx的行  /oldboy/p         # 按照匹配字串的方式模式查詢

              4 過濾範圍 //,//p

         示例1:輸出列印檔案的第三行

[root@oldboyedu-lnb ~]# sed -n '3p' oldboy.txt
test

        示例2:輸出檔案的3-6行  包含空行

                 格式: sed 'n,np' file
                          sed '3,6p' file
 [root@oldboyedu-lnb ~]# sed -n '3,6p' oldboy.txt
 test
 I like badminton ball ,billiard ball and chinese chess!
 my blog is http: blog.51cto.com

 示例3: 輸出檔案的最後一行 $

[root@oldboyedu-lnb ~]# sed -n '$p' oldboy.txt
11111111818181818
[root@oldboyedu-lnb ~]# sed -n '15,$p' oldboy.txt
hehe
$m
11111111818181818

  示例4:取出網路卡的第二行

[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'
inet 10.0.0.200  netmask 255.255.255.0  broadcast 10.0.0.255

  示例5:根據行號資訊,輸出多行內容(不連續)

[root@oldboyedu ~]# sed -n '1p;3p' person.txt
101,oldboy,CEO
103,Alex,COO

   根據內容資訊,輸出多行內容(連續)

      示例6: #將有oldboy到alex行的資訊都輸出出來 

 [root@oldboyedu ~]# sed -n '/oldboy/,/Alex/p' person.txt
 101,oldboy,CEO
 102,zhaoyao,CTO
 103,Alex,COO

      示例7:#將有oldboy和alex行的資訊都輸出出來   

  [root@oldboyedu ~]# sed -n '/oldboy/p;/Alex/p' person.txt
  101,oldboy,CEO
  103,Alex,COO
  106,oldboy,CIO 

      示例8:在檔案第一行新增資訊

        [root@oldboyedu ~]# sed  '1i100,oldgirl,UFO' person.txt
        100,oldgirl,UFO
        101,oldboy,CEO
        102,zhaoyao,CTO
        103,Alex,COO
        104,yy,CFO
        105,feixue,CIO
        106,oldboy,CIO

       示例9:在檔案最後一行新增資訊 

        [root@oldboyedu ~]# sed  '$a108,oldgirl,UFO' person.txt

        100,oldgirl,UFO

        101,oldboy,CEO

        102,zhaoyao,CTO

        103,Alex,COO

        104,yy,CFO

        105,feixue,CIO

        106,oldboy,CIO

        108,oldgirl,UFO

 測試:

       01. 在第三行後面新增oldboy.txt資訊

sed '3aoldboy.txt' person.txt

       02. 在第二行前面新增oldboy.txt資訊

 sed '2ioldboy.txt' person.txt

       03. 在有oldboy行的前面新增oldgirl 後面新增olddog資訊   

 sed -e '/oldboy/ioldgirl' -e  '/oldboy/aolddog' person.txt

     建立測試環境: 

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy01.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy02.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy03.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy04.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy05.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy06.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy07.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy08.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy09.txt

    -rw-r--r--. 1 root root      0 Oct 10 02:10 oldboy10.txt

       批量修改檔案的副檔名稱 將oldboyxx.txt副檔名修改為oldboyxx.jpg

    [root@oldboyedu oldboy]# ls oldboy*.txt|sed -r 's#(.*)txt#mv &(表示oldboy*.txt) \1(表  示oldboy*)jpg#g'

    mv oldboy01.txt oldboy01.jpg

    mv oldboy02.txt oldboy02.jpg

    mv oldboy03.txt oldboy03.jpg

    mv oldboy04.txt oldboy04.jpg

    mv oldboy05.txt oldboy05.jpg

    mv oldboy06.txt oldboy06.jpg

    mv oldboy07.txt oldboy07.jpg

    mv oldboy08.txt oldboy08.jpg

    mv oldboy09.txt oldboy09.jpg

    mv oldboy10.txt oldboy10.jpg

    mv oldboy.txt oldboy.jpg

1.5    sed 的模糊匹配

語法格式:

       grep '過濾的內容'  file

       sed '/過濾的內容/動作' file

       sed的增刪改查之檢視過濾檔案內容

       示例1:過濾包含http的行

[root@oldboyedu-lnb ~]# sed -n '/http/p' oldboy.txt
my blog is http: blog.51cto.com
our site is http:www.lizhenya.com

       示例2: 過濾包含http或lizhenya的行使用或者|

              語法格式:

                                    格式: sed 'n,np' file
                                      sed '3,6p' file
       [root@oldboyedu-lnb ~]# sed -nr '/http|lizhenya/p' oldboy.txt

        I am lizhenya teacher!

        my blog is http: blog.51cto.com

        our site is http:www.lizhenya.com

        lizhenyalizhenyalizhenyaaaaaaaaa

       示例3: 過濾字串的區間 使用行可以過濾區間 sed '1,3p' file

                  語法格式:

                  sed '/字串/,/字串/p' file 

 [root@oldboyedu-lnb ~]# sed -n '/test/,/not/p' oldboy.txt
 test
 I like badminton ball ,billiard ball and chinese chess!
 my blog is http: blog.51cto.com
 our site is http:www.lizhenya.com
 my qq num is 593528156
 aaaa,
 not 572891888887.

      工作中匹配日誌時間區間     

 [root@oldboyedu-lnb ~]# sed -n '/Aug  6 08:09:26/,/Aug  7 08:09:23/p' /var/log/messages 

區間模糊匹配的注意事項:

              a)模糊匹配的結束字元 如果檔案的後面有多個相同的字元 以第一個為結界

              b)模糊匹配的開始字元 如果檔案匹配字元結束 後還有開始的字元 沒有結束的字元 則匹配內容到檔案的末尾

1.6    sed 增加內容模式

sed 增加內容  臨時增加內容 只輸出到螢幕上 不會更改原始檔

        vi vim echo cat

           -a    append  追加      # 在當前行的下一行追加內容  當前3 第4行插入的新的內容

           -i     insert  插入      # 在當前行插入內容        當前3 插入3行前的內容

           -c   change  替換       # 把當前行的內容進行替換

         語法格式:

                     sed '3a 插入的內容' file

              示例1: 在當前行插入 

[root@oldboyedu-lnb ~]# sed '3i alex' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
hehe
test

              示例2: 在當前行追加新的內容     

[root@oldboyedu-lnb ~]# sed '3a prot=9777' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
test
prot=9777
      
   [root@oldboyedu-lnb ~]# sed '3,5a alex' oldboy.txt.bak
   I am lizhenya teacher!
   I teach linux.
   test
   alex
   alex
   I like badminton ball ,billiard ball and chinese chess!
   alex

              示例3: 替換第3行的內容為oldboyedu.com            替換整行        

[root@oldboyedu-lnb ~]# sed '3c oldboyedu.com' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com

 案例: 修改selinux的配置檔案selinux=disabled

            語法格式: sed -n '/模式/動作' file

                      sed -n '/被替換的內容/c 替換的內容' file    

[root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config
SELINUX=enforcing
[root@oldboyedu-lnb ~]# sed -in '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config
[root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
SELINUX=disabled

         方法2 按照行替換     

[root@oldboyedu-lnb ~]# sed -n '8c SELINUX=disabled' /etc/selinux/config
SELINUX=disabled
[root@oldboyedu-lnb ~]# sed -in '8c SELINUX=disabled' /etc/selinux/config
[root@oldboyedu-lnb ~]# sed 'a oldboyedu.com' oldboy.txt.bak  瞭解
I am lizhenya teacher!
oldboyedu.com
I teach linux.
oldboyedu.com
test
oldboyedu.com

1.7    sed的刪除

         語法結構:

         sed '/模式/動作' file           # 不加引數只是臨時刪除 不影響原始檔

         sed '3d' file

         sed '/oldboy/d' file

         示例1: 刪除第三行              

[root@oldboyedu-lnb ~]# sed '3d' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.

          示例2: 刪除1-3      

[root@oldboyedu-lnb ~]# sed '1,3d' oldboy.txt.bak
[root@oldboyedu-lnb ~]# sed '1,$d' oldboy.txt.bak 

           示例3: 字元匹配刪除 刪除包含linux的行

[root@oldboyedu-lnb ~]# sed '/linux/d' oldboy.txt.bak

           示例4: 刪除匹配的區間

[root@oldboyedu-lnb ~]# sed '/test/,/our/d' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
my qq num is 593528156

1.8    sed 的內容替換             

語法格式:

                sed 's#被替換內容#替換成什麼#g' file

              's@@@g'

              's///g'

              s  sub

              g  global 全域性替換

             示例1: 替換檔案中的每行第一個test為oldboy  瞭解

                                     s###  替換檔案中每行的第一個test

                                     sed 's###'  類似於 vim中的 %s###           

[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#' oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com test test test

            示例2: 替換檔案中所有的test為oldboyedu.com

                       sed 's###g' file 
[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#g' oldboy.txt.bak
                      永久替換              
 [root@oldboyedu-lnb ~]# sed -i 's#test#oldboyedu.com#g' oldboy.txt.bak

           示例3:把檔案第2,5行中的小寫字母刪除  有n 必須有p 才能輸出結果 

[root@oldboyedu-lnb ~]# sed -n '3,5p' oldboy.txt.bak|sed 's#[a-z]##g'
. . . .
I    .,    !
[root@oldboyedu-lnb ~]# sed  -n '3,5s#[a-z]##gp' oldboy.txt.bak
. . . .
I    .,    !

1.9    sed替換的注意事項:

         s### s///  看檔案中是否存在### ///     
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's//root/test/g'
sed: -e expression #1, char 9: unknown option to `s'
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's/\/root/test/g'
root:x:0:0:root:test:/bin/bash
[root@oldboyedu-lnb ~]#
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's#/root#test#g'
root:x:0:0:root:test:/bin/bash
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's#\#hehe#test#g'
root:x:test0:0:root:/root:/bin/bash

1.10    sed 的後向引用

                     語法格式: 先保護  後引用

                             ()      引用()中的內容 支援正則
                      \1      表示第一個()的內容
                      \2      表示第二個()的內容

              呼叫()內容的前面和後面可以加任意的內容

[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#\1#g'
 123456
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#<<\1>>#g'
<<123456>>
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#hehe\1hehe#g'
hehe123456hehe
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#1111\11111#g'
11111234561111
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#\1#g'
123456
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#<\1>#g'
<123><456>
[root@oldboyedu-lnb ~]# echo 123456|grep '[0-9]{3}' -o
[root@oldboyedu-lnb ~]# echo 123456|egrep '[0-9]{3}' -o
123
456

   案例: sed 後向引用獲取IP地址

[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#^.*inet (.*)  netmask.*$#\1#g'
10.0.0.200
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*) netmask.*$#\1#g'
inet
[root@oldboyedu-lnb ~]# ifconfig eth0|sed –n '2p'|sed-r's#(^.*inet )(.*)(  netmask.*$)#\3#g'
netmask 255.255.255.0  broadcast 10.0.0.255
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*)(  netmask.*$)#\2#g'
10.0.0.200    

使用ip add 取出IP地址和子網掩碼

[root@oldboyedu-lnb ~]# ip add|grep -n .
[root@oldboyedu-lnb ~]# ip add|sed -nr '9s#^.*net (.*)/24.*$#\1#gp'
10.0.0.200
[root@oldboyedu-lnb~]# ip add |sed -n '9p' |sed -r 's#^.*brd(.*)scop.*$#\1#g'
10.0.0.255
[root@oldboyedu-lnb~]# ip add |sed -nr '9s#^.*brd(.*)scop.*$#\1#gp'
10.0.0.255

   1.11   練習題

    1.11.1   將/etc/passwd檔案的第3行到第7行另存為/tmp/passwd

[root@oldboyedu-lnb~]# cat /etc/passwd |sed -n '3,7p' > /tmp/passwd
[root@oldboyedu-lnb~]# cat /tmp/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

   1.11.2   在/tmp/passwd檔案中的第3行前插入下面兩行文字

                  good good study, day day up.

                  Come here, change yourself.

[root@oldboyedu-lnb~]# sed  '3i\ngood good study, day day up.\nCome here,change yourself.' /tmp/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ngood good study, day day up.
Come here,change yourself.
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

  1.11.3    將/tmp/passwd檔案中的所有/sbin/nologin替換為/bin/bash

[root@oldboyedu-lnb~]# sed -n 's#/sbin/nologin#/bin/bash#gp' /tmp/passwd
daemon:x:2:2:daemon:/sbin:/bin/bash
adm:x:3:4:adm:/var/adm:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/bin/bash

  1.11.4   刪除/tmp/passwd檔案中包含bin單詞的行

[root@oldboyedu-lnb~]# sed '/\<bin\>/d' /tmp/passwd1
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

1.12    小結sed

              增刪改查替換

              檢視:

                

                      -n  取消預設輸出

                      -r  支援擴充套件正則

                      -i  更改原始檔

                      sed -n '3p' file

                                    1,3p

                                    3,$p

                      sed -n '/root/p' file

                      sed -n '/root/,/alex/p' file

        增加替換:

            

                     -i 

                     -a

                     -c

        sed '3i 新的內容' file

       sed '3a 追加內容' file

       sed '3c 替換整行內容' file 

              組合使用:

sed '3,5c oldboyedu' file
sed '/root/c oldboyedu' file
修改原始檔 -i引數
sed的替換:
sed 's#替換誰#替換的內容#g' file
cat file |sed 's###g'
sed '3,5p' file|sed 's###g'
組合使用
sed -n '3,5s###gp' file
sed的後向引用
sed -r 's#()#\1#g'

 PS: Linux中大部分的命令   -V 都是檢視版本資訊

grep的引數

            -n    顯示匹配到內容的行號

           -v    取反

           -o    顯示匹配過程

           -i    不區分大小寫

           -E    支援擴充套件正則

           -R    遞迴查詢檔案內容

           -w    過濾單詞

           -c    統計字串在檔案中出現的次數

           -A   顯示當前查詢到的內容往下n行       瞭解

           -B    顯示當前查詢到的內容往上n行       瞭解

           -C    顯示當前查詢到的內容上下各n行    瞭解   

 

[root@oldboyedu-lnb ~]# grep oldboy 1.txt
alexoldboylidao
oldboy
oldboyedu.com
[root@oldboyedu-lnb ~]# grep -w oldboy 1.txt
oldboy
[root@oldboyedu-lnb ~]# grep linux -A3 oldboy.txt.bak
 I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com
I like badminton ball oldboyedu.com,billiard ball and chinese chess!
[root@oldboyedu-lnb ~]# grep like -B3 oldboy.txt.bak
I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com
I like badminton ball oldboyedu.com,billiard ball and chinese chess!
[root@oldboyedu-lnb ~]# grep linux -C1 oldboy.txt.bak
I am lizhenya teacher!
I teach linux.
oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com

 

相關文章