sed命令詳解+示例


參考鏈接:https://blog.csdn.net/jsut_rick/article/details/78287737

一、功能簡介

sed(Stream EDitor),是一種流文件編輯器,其特點為:

1、非交互式。處理文件時,把當前處理的行存儲在臨時緩沖區(稱為“模式空間”(Pattern Space))中,即它是基於模式匹配過濾及修改文本。

2、逐行處理,sed 命令在緩沖區中一次處理一行內容,處理完成后,把緩沖區的內容送往屏幕,接着處理下一行,直到文件末尾。

正常情況下,sed命令所做的處理只是把操作結果(包括打印、刪除等)輸出到當前終端屏幕,而並不會對原始文件做任何更改。若希望直接修改文件內容,應添加選項 -i 。為了避免生產環境中因誤操作導致系統故障,使用時要謹慎。

sed 主要用來編輯一個或多個文件,簡化對文件的反復操作(如:輸出、刪除、替換、復制、剪切、導入、導出等各種操作)或者用來編寫轉換程序等。

二、語法格式

格式1:前置命令 | sed [選項] '[定址符]處理動作’

格式2:sed [選項] '[定址符]處理動作’文件 [input-file]

其中:處理動作可以由-e指定多個處理動作,input-file為輸入文件,可指定多個。

三、語法說明

1、選項說明

  • -i:直接修改文件內容,而不是輸出到終端。
  • -n:安靜模式,屏蔽默認輸出(全部文本),只有經過sed特殊處理的那一行才會被列出來。
  • -e :指定sed動作,可以由多個-e指定多個動作。
  • -r:啟用擴展的正則表達式,若與其他選項一起使用,應作為首個選項。
  • -f :直接將sed的動作寫在一個文件內,-f filename則可以運行filename 內的sed動作。
  • --help:顯示幫助。
  • --version:顯示版本。
  • -{}:可組合多個命令,以分號分隔。

2、動作說明

​ [n1[,n2]] function

  • 其中[n1[,n2]]稱為定址符,用來定義需要操作的文本,如指定處理的起、止行數。

  • n1, n2 不見得會存在,一般代表“選擇進行動作的行數”,舉例來說,如果我的動作是需要在 10 到 20 行之間進行,則寫作“10,20動作行為”。

  • 地址可表示為文本的“行號”,或者用來匹配的“/正則表達式/”

  • 省略定址符時,默認逐行處理全部文本。

​ fuction為編輯指令,可以為增刪改查等指令

  • a :新增, a 的后面可以接字串,而這些字串會在新的一行出現(目前的下一行)~
  • c :取代, c 的后面可以接字串,這些字串可以取代 n1,n2 之間的行!
  • d :刪除,因為是刪除啊,所以 d 后面通常不接任何內容;
  • i :插入, i 的后面可以接字串,而這些字串會在新的一行出現(目前的上一行);
  • p :打印,亦即將某個選擇的數據印出。通常 p 會與參數 sed -n 一起運行
  • s :替換,通常這個s的動作可以搭配正規表示法!例如 1,20s/old/new/g。

四、典型示例

image-20210704221939438

替換擔任的分隔“/”,可改用其他字符,如#、&等,便於修改文件路徑

示例:把/bin/bash替換為/sbin/sh (/etc/passwd)

sed "s/\/bin\/bash/\/sbin\/sh/" /etc/passwd
或者
sed "s#/bin/bash#/sbin/sh#" /etc/passwd

image-20210704222457796

處理多行文本:修改后的文本有多行時,以換行符\n分隔,或使用\強制換行

示例:修改主機名配置文件

1)確認修改前的配置 # cat /etc/sysconfig/network

2)使用sed修改主機名配置所在行的內容(c整行替換)

sed  '/^HOSTNAME/cHOSTNAME=mysvr.tarena.com' /etc/sysconfig/network 

示例:修改hosts文件,添加新的記錄

1)確認修改前的配置 # cat /etc/hosts

2)使用sed修改hosts文件,添加兩行新紀錄(a追加)

sed  -i  '$a192.168.4.5  svr5.tarena.com svr5\
> 119.75.217.56  www.baidu.com' /etc/hosts

常見處理操作示例:

image-20210704223010009image-20210704223053056image-20210704223118364

文件導入導出操作

基本動作:

  • r 動作應結合-i選項才會存入,否則只輸出
  • w 動作以覆蓋的方式另存為新文件

image-20210704224909123

sed -n ‘/^XX/w d.txt’ reg.txt 與 sed -n ‘/^XX/p d.txt’ reg.txt > d.txt操作效果相同

換行:****n和N的區別

image-20210704225815084

n:打印當前模式空間內容,然后讀取下一行並替代當前模式空間的內容。如果讀取不到下一行sed則會不運行之后的命令。

image-20210704225742585

​ 上面命令過程是這樣:

  1. 先讀取第一行進模式空間(以后簡稱為1)

  2. 執行命令n,過程如下

  3. 打印1到輸出

  4. 讀取2並覆蓋到模式空間

  5. 執行命令d,過程如下

  6. 刪除模式空間的內容

  7. 立即執行下一循環(d命令在運行后會直接執行下一循環,所以它並不會執行之后的命令和打印模式空間,具體d介紹會留在下次分享)

  8. 按照上面的流程循環執行…….直到讀取到11(最后一行),11的具體過程如下

  9. 讀取11進模式空間

  10. 運行命令n,不過讀取不到下一行

  11. 因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令d

  12. 加回換行符並打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11

  13. 已經是文件尾,sed結束運行

N:讀取下一行並且附加到當前模式空間內,如果讀取不到下一行sed則會不運行之后的命令。

image-20210704230232407

​ 上面命令過程是這樣:

  1. 讀取1進模式空間

  2. 執行命令N

  3. 讀取2並附加到模式空間,當前模式空間內容為“1\n2”

  4. 執行命令a—

  5. 在模式空間后附加一行‘—’當前模式空間內容為“1\n2\n—"

  6. 打印模式空間內容

  7. 循環執行直到讀取11進模式空間,11的具體過程如下

  8. 讀取11進模式空間

  9. 執行命令N,不過讀取不到下一行

  10. 因為讀不到,所以sed退出所有的命令,也就是說它不會執行命令a

  11. 加回換行符並打印模式空間的內容到輸出,當前模式空間內容為11,所以輸出11

  12. 已經是文件尾,sed結束運行。

五、綜合運用

  1. 刪除文件中每行的第二個、最后一個字符

    分兩次替換操作,第一次替換掉第2個字符,第二次替換掉最后一個字符:

    sed 's/.//2;s/.$//' nssw.txt 
    
  2. 將文件中每行的第一個、第二個字符互換

    每行文本拆分為“第1個字符”、“第2個字符”、“剩下的所有字符”三個部分,然后通過替換操作重排順序為“2-1-3”:

    sed -r 's/^(.)(.)(.*)/\2\1\3/' nssw.txt
    
  3. 將第一個字符與最后一字符對調:

    sed -r “s/^(.)( .*)(.)$/\3\2\1/” nssw.txt
    
  4. 刪除文件中所有的數字、行首的空格

    sed -r 's/[0-9]+//g;s/^( )+//' nssw2.txt
    
  5. 為文件中每個大寫字母添加括號

     sed 's/[A-Z]/(&)/g' nssw.txt        //使用“&”可調用s替換操作中的整個查找串 或者  sed -r "s/([A-Z])/(\1)/g"  nssw.txt
    
  6. 修改默認運行級別

    sed -i '/^id:/s/3/5/' /etc/inittab            //將默認運行級別修改為5grep "^id:" /etc/inittab                      //確認修改結果
    
  7. 修改IP地址(網段):修改IP地址的網段部分,主機地址不變。

    直接修改網卡eth0的配置文件,檢查原有的配置內容:

    cat /etc/sysconfig/network-scripts/ifcfg-eth0IPADDR=192.168.4.4
    

    若希望將IP地址192.168.4.4修改為172.16.16.4,則應該定位到“IPADDR”所在的行,執行相應的替換(僅測試,尚未修改):

    sed '/^IPADDR/s/192.168.4.4/172.16.16.4/' \/etc/sysconfig/network-scripts/ifcfg-eth0 | grep "^IPADDR"
    

    要求只修改網段地址時,可以利用擴展正則表達式的 \1、\2、……等調用,分別對應此前第1個、第2個、…… 以 ()包圍的表達式所匹配的內容。

    所以上述操作可以改為如下(啟用擴展匹配應添加 -r 選項):

    sed -r -i '/^IPADDR/s/192.168.4.(.*)/172.16.16.\1/' \/etc/sysconfig/network-scripts/ifcfg-eth0
    

    確認修改結果:

    grep "^IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
    
  8. 調整httpd服務配置,更改網站根目錄

    由於需要替換的字符串中有 / ,為了避免與sed替換操作的分隔混淆,可以使用其他字符作為替換分隔,比如可改用“s#old#new#”的方式實現替換:

    sed -i 's#/var/www/html#/opt/wwwroot#' /etc/httpd/conf/httpd.confgrep "^DocumentRoot" /etc/httpd/conf/httpd.confDocumentRoot "/opt/wwwroot"
    
  9. 修改/etc/hosts

    sed -i ‘1a 1.1.1.1 域名’ /etc/hosts
    
  10. 打印奇、偶數

    image-20210704230724813

  11. 打印行號image-20210704230849992

  12. 將行號和內容一行顯示

    image-20210704231236416

    N代表 將第二行追加到第一行后面表示為1\n2 。這樣將 \n 替換成 空格就行了 s/\n/ /


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM