文本處理工具——sed

事前說明一下,有的時候我可能用m1,有時候有用了/data/m1,其實這兩個在這篇文章裏是一個意思,前面是相對路徑表示,後面是絕對路徑。不好意思,正在努力改掉這個壞習慣,以後在一篇文章裏儘量保持一致。

簡介

  1. Stream EDitor, 行編輯器
  2. sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時
    緩衝區中,稱爲“模式空間”(pattern space),接着用sed命令處理緩衝區中的
    內容,處理完成後,把緩衝區的內容送往屏幕。然後讀入下行,執行下一個循環。
    如果沒有使諸如‘D’ 的特殊命令,那會在兩個循環之間清空模式空間,但不會清
    空保留空間。這樣不斷重複,直到文件末尾。文件內容並沒有改變,除非你使用重
    定向存儲輸出
  3. 功能:主要用來自動編輯一個或多個文件,簡化對文件的反覆操作,編寫轉換程序等
  4. 參考: http://www.gnu.org/software/sed/manual/sed.html

用法

    1.在option可以選擇也可不選擇加入選項,常見選項的有:

  • 格式:sed [option]... 'script' filepath...  
  • -n :不輸出模式空間的內容到屏幕,即不自動打印。(PS:sed會默認打印模式空間的內容,使用-n可以避免重複打印)
  • -e :多點編輯
  • -r  :支持擴展正則表達式
  • -i.bak :先對文件進行備份再進行原處編輯 (sed -i就意味着直接對文件進行修改,所以還是sed -i.bak保險,先備份)

     2.1  'script' 是地址命令,簡言之就是在單引號里加入地址定界和編輯命令

 

  • 地址定界:分四種情況。
  • (1)不給地址:那麼sed就會對全文進行處理,比如sed  ''  /data/m1結果就是將m文件中的內容全部打印到屏幕
  • (2)單地址,這個時候地址定界後面就要接編輯命令了。
  • #:指定第#行。比如sed '2p' /data/m1,(p是打印當前模式空間內容,追加到默認輸出之後)此時結果是m1文件中內容全部被打印出來,但是第2行被打印兩次,要是想取消默認打印,-n瞭解一下。
  • $:指定最後一行,用法同上一條。
  • /pattern/:匹配與pattern相似的行

 

  • (3)地址範圍:可以指定範圍來匹配
  • #,#    匹配第#行到第#行的內容,演示如下,顯示第一行到第三行的內容,這裏我忘記加-n了,所以sed又默認打印了一遍。 

 

  • #1,+#   匹配第#1行到第#1+#行的內容,比如'1,+2'就是第一行到第三行,以此類推。注意sed不識別類似'3,-1'這樣的寫法。
  • /partern1/,/partern2/   sed還支持對兩個模式範圍內進行操作。

  • #,/partern1/  指定行號和模式進行操作

  •  (4)~:步進
  • 舉個栗子:1~2表示從第一行開始,每隔兩行進行顯示,可以理解爲只顯示奇數行。
  • 那麼2~2就是從第二行開始每隔兩行顯示,即顯示偶數行。

 前面說到'script'分爲兩部分,地址定界和編輯命令。下面介紹一下編輯命令。

2.2 編輯命令

 

把he全部替換成ppppp

         這個時候加上g就可以了

  • d:刪除模式空間匹配的行,並立即啓用下一輪循環。emmmmm,簡單理解就是刪除指定行,不讓它顯示了。但這只是刪除模式空間匹配的行,真實文件裏內容並未被刪除。只有選項選擇i纔會修改。
  •  p:打印當前模式空間內容,追加到默認輸出之後。之前用到過,值得注意的是sed本身默認會打印,加上p之後如果沒有其它命令的話就會打印兩次。
  • a [\]text:在指定行後面追加文本,支持使用\n實現多行追加,不光是換行,這裏\是告訴計算機\以後都是要加入的內容。(PS:本來學到的是用\符號,但是我手欠又試了一下/符號,居然也闊以)
  • i [\]text:在行前面插入文本,用法同上一條。
  • c [\]text:替換行爲單行或多行文本,用法同上一條。
  • w /path/somefile: 保存模式匹配的行至指定文件。舉個栗子^_^,
    sed '/th/w /data/m3' /data/m1

    從m1文件中匹配包含th的行,並把該行寫到m3文件中,m3不用事先創建,這裏自動創建並寫入。

  • r /path/somefile:讀取指定文件的文本至模式空間中匹配到的行後,跟上一條用法相似。
  • =: 爲模式空間中的行打印行號
  • !:模式空間中匹配行取反處理。
  • s///:查找替換,支持使用其它分隔符,s@@@,s###
  • 替換標記:
  • ①g: 行內全局替換。一行可能出現多個匹配的字符,如果僅僅用s///就會出現只替換前面出現的字符而後面的則不會替換。
  • ②p: 顯示替換成功的行
  • ③w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中。

當然,本文所用的文件內容很簡單,其實實際中遇到的文件很複雜,要精確匹配並修改還需要紮實的正則表達式基礎。咳咳,這是題外話。

   3. 高級編輯命令

模式空間與保持空間:都在內存裏,保持空間用來放置模式空間裏未處理完的內容。

  • P(大寫) :打印模式空間開端至\n內容,並追加到默認輸出之前
  • h :把模式空間中的內容覆蓋至保持空間中
  • H:把模式空間中的內容追加至保持空間中
  • g :從保持空間取出內容覆蓋至模式空間
  • G:從保持空間取出數據追加至模式空間
  • d :刪除模式空間中的行
  • D:如果模式空間包含換行符,則刪除直到第一個換行符的模式空間中的文本,並不會讀取新的輸入行,而使用合成的模式空間重新啓動循環。如果模式空間不包含換行符,則會像發出d命令那樣啓動正常的新循環(舉個栗子:模式空間裏有三行數據,那D就只刪除第一行的,d是全刪除)
  • n :讀取匹配到的行的下一行覆蓋至模式空間
  • N:讀取匹配到的行的下一行追加至模式空間
  • x :把模式空間中的內容與保持空間中的內容進行互換

 看看能不能猜到下面的命令含義

sed -n 'n;p' FILE
sed '1!G;h;$!d' FILE
sed‘N;D’ FILE
sed '$!N;$!D' FILE
sed '$!d' FILE
sed ‘G’ FILE
sed ‘g’ FILE
sed ‘/^$/d;G’ FILE
sed 'n;d' FILE
sed -n '1!G;h;$p' FILE


再附一道練習題
利用sed 取出ifconfig命令中本機的IPv4地址。
 

ifconfig ens33|sed -n '2p'|sed -nr 's/.*inet[[:space:]](.*)[[:space:]]netmask.*/\1/p'

或者

查詢centos7版本的
ifconfig ens33|sed '2!d'|sed -r -e 's/^[[:space:]].*inet//' -e 's/[[:space:]].*//'
ifconfig ens33|sed -n '2p'|sed -r 's@(.*inet[[:space:]](.*)([[:space:]]netmask.*)@\2@'
ifconfig ens33|sed -n '2p'|sed -r 's@.*inet[[:space:]](.*)[[:space:]]netmask.*@\1@'
centos6版本
ifconfig eth0|sed -n '2p'|sed -r 's/.*addr:(.*)Bcast.*/\1/'

三選一。 6和7版本的ip地址格式不同,細節可以自己發現。

勤能補拙,多練。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章