1. 程式人生 > >Linux學習總結(二十)正則三劍客之sed

Linux學習總結(二十)正則三劍客之sed

sed

sed
流式編輯器,針對文檔的行來操作的

一 查找打印

1.打印某行
格式: sed -n ‘n‘p filename 單引號內的n代表數字,表示第幾行
例如:打印第二行
sed -n ‘2‘p /etc/passwd
也可以指定區間,比如打印前三行
sed -n‘1,3‘p /etc/passwd
打印所有的行
sed -n ‘1,$‘p /etc/passwd

  1. 打印包含某個字符串的行,相當於grep
    格式 : sed -n ‘/字符串/‘p filename
    例如 sed -n ‘/root/‘p /etc/passwd
    -e 可以實現在一條命令中對文檔進行多次操作,意思是針對某個文檔並行操作幾次,兩個-e,就是兩次操作,依次類推。例如:
    sed -e ‘1,3‘p -e ‘/root/‘p -n /etc/passwd
    該命令等價於 sed -n ‘1,3‘p /etc/passwd;sed -n ‘/root/‘p /etc/passwd
  2. 我們剛學過grep 有個-i 選項,可以忽略大小寫匹配,sed 同樣可以,加一個I選項。例如
    sed -n ‘/root/‘Ip /etc/passwd

    二 刪除

    1.刪除指定的行,直接舉例
    sed ‘1,3‘d /etc/passwd 刪除前三行,剩余的行會在屏幕打印
    2.刪除根據字符串查找出的行
    sed ‘/root/‘d /etc/passwd 刪除帶有root的行,顯示剩余的行
    3.-i 選項可以直接操作源文件。那麽我們拷貝一份/etc/passwd再操作

    cp /ect/passwd ./test.txtt
    sed -i ‘1,3‘d test.txt

    三 查找替換

    格式為: sed ‘1,n s/new/old/g‘ filename
    1,n n為數字,指定要替換的區域
    s 替換標識符
    new 用來替換的字符串
    old 將被替換的字符串
    g 標示全局替換
    1.將上面的test.txt文件,前10行中的root全部替換為boot
    sed ‘1,10 s/root/boot/g‘ test.txt 對於該需求我們還可以用正則,例如
    sed ‘1,10 s/ro+t/boot/g‘ test.txt -r 我們發現我們多用了一個-r,原因是
    sed無法直接識別+,它的作用類似於我們grep用的-E選項,當然我們也可以用轉意符

    技術分享圖片
    2.將test.txt中以:號分割的第一段和最後一段交換位置
    該問題的重點是我們怎麽用正則表達要交換的字符串,標示出的字符串要怎麽交換,既讓目標位置交換,又不破壞其他字符。我們給出思路和結果
    以:號分割,我們將一行看作三段。
    字符串1:字符串2:字符串3
    字符串1和字符串2,我們可以非冒號字符匹配整個字符串,([^:]+)
    字符串2,我們不對其操作,直接貪婪匹配 (.*)
    那麽最後的結果為:

sed ‘s/([^:]+):(.*):([^:]+)/\3:\2:\1/g‘ test.txt -r
我們打印前三行看下結果:
技術分享圖片
3.把test.txt中英文字母全刪除。
也就是把英文字母全部找出來替換為空。
sed ‘s/[a-zA-Z]//g‘ test.txt,我貼出部分結果
技術分享圖片
4.在test.txt 文件中行首都加上#:字符
分析: 我們同樣用替換的辦法,被替換對象就是整行內容,我們用貪婪匹配 (.*) 用來替換的部分就是給原來字符行首加上#: 原來字符可以用&標示,也可以用\1標示,因為只有一段就是第一段,結果為:

sed ‘s/(.*)/#:&/g‘ test.txt -r 或者 sed ‘s/(.*)/#:\1/g‘ test.txt -r
技術分享圖片
5.刪除test.txt 中的所有特殊字符
解讀:特殊字符就是非數字非英文字母

sed ‘s/[^0-9a-zA-Z]//g‘ test.txt
技術分享圖片
6.把test.txt中出現的第一個單詞和最後一個單詞調換位置
分析:很顯然分為三段處理,第一個單詞,我們用字母開頭一直匹配完就可以 (^[a-zA-Z]+)
中間一段從非字母開頭一直匹配到非字母結束,中間匹配任意字符 ([^a-zA-Z].*[^a-zA-Z])
最後一個單詞用字母匹配至末尾就可以 ([a-zA-Z]+$)
最後的結果為:

sed ‘s/(^[a-zA-Z]+)([^a-zA-Z].*[^a-zA-Z])([a-zA-Z]+$)/\3\2\1/g‘ test.txt -r
技術分享圖片
7把test.txt中的第一個數字移動到本行末尾
分析:也是分為三段,第一段非數字開頭匹配 (^[^0-9]+), 第二段匹配數字([0-9]+)
第三段非數字開頭,後面匹配任意到結尾([^0-9].*$),第二段和第三段交換位置就可以了。結果為:

sed ‘s/(^[^0-9]+)([0-9]+)([^0-9].*$)/\1\3\2/g‘ test.txt -r
技術分享圖片

Linux學習總結(二十)正則三劍客之sed