18.三劍客之sed

1.sed簡介


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

grep:單純的文本查找匹配,無法對數據進行修改
sed:可以文本查找,也可以對文本編輯修改(替換、刪除)
awk:格式化複雜的文本

格式:
1、sed [options] ‘command’ file(s) command=條件和處理動作,若command中包含變量,要用”command”
2、sed [options] -f scriptfile file(s)

常用選項:
-n:不輸出模式空間內容到屏幕,即不自動打印
-e: 多點編輯
-f:/PATH/SCRIPT_FILE: 從指定文件中讀取編輯腳本
-r: 支持使用擴展正則表達式
-i.bak: 備份文件並原處編輯

2.選項用法


準備文件:cp /etc/passwd /data/

1.-i:修改源文件,後面一定要接文件cat

[root@Centos7 data]#sed -i '2d' passwd
錯誤寫法:
[root@Centos7_101 data]#cat -n passwd | sed -i '2d'
sed: no input files

2.-i.bak:修改源文件之前,備份以.bak結尾

[root@Centos7 data]#sed -i.bak '2d' passwd

-f:調用文本

[root@Centos7 data]#sed -r '/^[^#]/s/[[:alpha:]]/\u&/g' /etc/fstab 
[root@Centos7 data]#vim sed.script
[root@Centos7 data]#cat sed.script 
/^[^#]/s/[[:alpha:]]/\u&/g
[root@Centos7 data]#sed -r -f sed.script /etc/fstab 

[root@Centos7 data]#cat sed.script 
2s/.*inet //;s/ netmask.*//p
[root@Centos7 data]#ifconfig ens33 | sed -rnf sed.script 
172.16.34.101 

-e:多命令編輯

[root@Centos7_101 data]#ifconfig ens33 | sed -rne '2s/.* inet //p' -e 's/ netmask.*//p' -e 's/172/192/p'
172.20.34.101  netmask 255.255.0.0  broadcast 172.20.255.255 #這是第一條命令執行的結果
172.20.34.101 #這是在第一條結果的基礎上執行後的結果
192.20.34.101 #這是在第2條結果基礎上執行後的結果

等價於用;把命令隔開

[root@Centos7_101 data]#ifconfig ens33 | sed -rne '2s/.* inet //p;s/ netmask.*//p;s/172/192/p'

3.條件地址


  1. 表示全部打印在屏幕上
    #sed -n ‘p’ passwd

2.打印指定行,打印第2行

[root@Centos7 data]#sed -n '2p' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin

[root@Centos7 data]#ifconfig ens33 | sed -n '2p'
        inet 172.16.34.101  netmask 255.255.0.0  broadcast 172.16.255.255

3.顯示最後一行

[root@Centos7 data]#sed -n '$p' passwd 
chen:x:1000:1000:chen:/home/chen:/bin/bash

4.指定範圍行,’1,3p’:第1到第3行

[root@Centos7 data]#sed -n '1,3p' passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

5.正則表達匹配行,’/正則表達式/’,選項-r支持擴展正則表達式。

[root@Centos7 data]#sed -n '/^U/p' /etc/fstab   顯示U開頭的行
UUID=ba708318-e653-437f-b7e7-2c81ae7cbbe2 /                       xfs     defaults        0 0
UUID=12984512-ec20-4b99-a000-34b8ba546a14 /boot                   xfs     defaults        0 0
UUID=9c9b025f-487c-42cd-9bec-6f9c582cdbe5 /data                   xfs     defaults        0 0
UUID=210c8f6a-8a2a-40cc-bd3b-6cb106159332 swap                    swap    defaults        0 0

6.打印匹配/dev/sd,需要加轉義符\/dev\/sd

[root@Centos7 data]#df -h | sed -n '/\/dev\/sd/p'    
/dev/sda2        20G  4.0G   16G  20% /
/dev/sda5        27G   33M   27G   1% /data
/dev/sda1      1014M  165M  850M  17% /boot

7.打印第1行,和第1行後面的3行

[root@Centos7 data]#cat -n passwd | sed -n '1,+3p'
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin

8.從第3行開始,到以f開頭的範圍打印出來

#sed -n '3,/^f/p' passwd

9.匹配範圍,’/正則表達式/,/正則表達式/’

10.打印奇數’1~2’和偶數’2~2’行,1~3,從1開始隔3個數

[root@Centos7 data]#seq 10|sed -n '1~2p'
1
3
5
7
9
[root@Centos7 data]#seq 10|sed -n '2~2p'
2
4
6
8
10

總結:條件大致分爲:指定行、範圍行、正則表達式、範圍正則表達式、行加正則表達式

4.處理動作


編輯命令:

d: 刪除模式空間匹配的行,並立即啓用下一輪循環
p:打印當前模式空間內容,追加到默認輸出之後
a []text:在指定行後面追加文本,支持使用\n實現多行追加
i []text:在行前面插入文本
c []text:替換行爲單行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:讀取指定文件的文本至模式空間中匹配到的行後
=: 爲模式空間中的行打印行號
!:模式空間中匹配行取反處理
s///:查找替換,支持使用其它分隔符,s@@@,s###
替換標記:
g: 行內全局替換
p: 顯示替換成功的行
w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中


d:刪除
1.刪除指定行

[root@Centos7 data]#cat -n passwd | sed '2d'
     1  root:x:0:0:root:/root:/bin/bash
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
……
[root@Centos7 data]#cat -n passwd | sed '2,20d'
     1  root:x:0:0:root:/root:/bin/bash
    21  gluster:x:995:992:GlusterFS daemons:/var/run/gluster:/sbin/nologin

[root@Centos7 data]#cat -n passwd | sed -n ‘2~2d;p’
命令解析:第一行是否滿足’2~2d’,不滿足,繼續匹配下一條命令p,滿足,然後打印到屏幕上
繼續處理下一行,第二行滿’2~2d’,滿足,就刪除,下一條命令就不用管了,繼續依次執行後面行

把偶數行刪掉,奇數行打印出來,等同:#sed -n ‘1~2p’

2.用正則表達式匹配到的行刪掉

[root@Centos7 data]#sed '/^#/d' /etc/fstab

3.刪除空白行

#sed '/^$/d' demo.txt

a:行後追加
1.指定行添加

[root@Centos7 data]#cat -n passwd | sed '1,20a new line'
     1  root:x:0:0:root:/root:/bin/bash
new line
     2  bin:x:1:1:bin:/bin:/sbin/nologin
new line
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin

a後面加,告訴a,\後面的所有東西就是要追加的,包括空格

[root@Centos7 data]#cat -n passwd | sed '1,20a\  new line'
     1  root:x:0:0:root:/root:/bin/bash
  new line
     2  bin:x:1:1:bin:/bin:/sbin/nologin
  new line
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
  new line

2.添加多行字符串間用\n換行即可

[root@Centos7 data]#cat -n passwd | sed '1,20a\ new line1\n new line2'
     1  root:x:0:0:root:/root:/bin/bash
 new line1
 new line2
     2  bin:x:1:1:bin:/bin:/sbin/nologin
 new line1
 new line2

3.匹配正則表達式

[root@Centos7 data]#sed '/^# Source .*/a\hello world' /root/.bashrc

i:前面行追加(語法和a同理)

c:滿足條件行替換(語法和a同理)

[root@Centos7 data]#sed '/^# Source .*/c\ hello world' /root/.bashrc

w:滿足條件行保存到指定文件
1.指定行

[root@Centos7 data]#cat -n passwd | sed -n '1,3w /data/f3'
[root@Centos7 data]#cat f3 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin

2.正則表達式匹配行

[root@Centos7 data]#sed -n '/^U/w /data/f2' /etc/fstab 
[root@Centos7 data]#cat f2
UUID=ba708318-e653-437f-b7e7-2c81ae7cbbe2 /                       xfs     defaults        0 0
UUID=12984512-ec20-4b99-a000-34b8ba546a14 /boot                   xfs     defaults        0 0
UUID=9c9b025f-487c-42cd-9bec-6f9c582cdbe5 /data                   xfs     defaults        0 0
UUID=210c8f6a-8a2a-40cc-bd3b-6cb106159332 swap                    swap    defaults        0 0

r:滿足條件行後面添加指定文件內容

[root@Centos7 data]#cat addfile 
cjx:x:222:2222:cjx:/sbin:/sbin/nologin
[root@Centos7 data]#cat  passwd | sed '1r /data/addfile'
root:x:0:0:root:/root:/bin/bash
cjx:x:222:2222:cjx:/sbin:/sbin/nologin    addfile內容添加到第1行後面

=:滿足條件行前面行顯示行號

[root@Centos7 data]#sed '1,3=' passwd 
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3

!:取反顯示行號,效果與=相反


s///:替換,達到增、刪、改功能(重點)

#who am i | awk '{print $5}'|sed 's/[()]//g'
172.16.34.100

[root@Centos7 data]#sed 's/root/ROOT/' passwd 
ROOT:x:0:0:root:/root:/bin/bash  只替換一個root

要想全局替換

[root@Centos7 data]#sed 's/root/ROOT/g' passwd 
ROOT:x:0:0:ROOT:/ROOT:/bin/bash

還可以指定第2個root,再開始替換

[root@Centos7 data]#sed 's/root/ROOT/2g' passwd 
root:x:0:0:ROOT:/ROOT:/bin/bash

正則表達式分組:-r 表示支持擴展正則表達式 -n表示關掉默認打印,g表示全局替換,p表示滿條件的打印出來
\1表示正則表達式的一個分組,分組後面加er
rooter:x:0:0:rooter:/rooter:/bin/bash
[root@Centos7 data]#sed -rn ‘s/(root)/\1er/gp’ passwd
operator:x:11:0:operator:/rooter:/sbin/nologin

例子1

[root@Centos7 data]#cat /etc/default/grub | sed -r 's/(quiet)/\1 net.ifnames=0/'
[root@Centos7 data]#cat /etc/default/grub | sed -r 's/(LINUX.*)"/\11 net.fnames=0"/'

還可以先查找滿足條件的行,下例先用正則表達式匹配LINUX的行

[root@Centos7 data]#cat /etc/default/grub | sed -r '/LINUX/s/(.*)$"/\11 net.fnames=0"/'
[root@Centos7 data]#cat /etc/default/grub | sed -r '/LINUX/s/"$/ net.fnames=0"/'

例子2,用seq提取ip

[root@Centos7 data]#ifconfig ens33 | sed -n '2p'
        inet 172.16.34.101  netmask 255.255.0.0  broadcast 172.16.255.255

方法1:把ip前後刪掉,”;”可以添加多條命令

[root@Centos7 data]#ifconfig ens33 | sed -rn '2s/.*inet //;s/ netmask.*//p'
172.16.34.101 

方法2:用分組實現

[root@Centos7 data]#ifconfig ens33 | sed -rn '2s/(.*inet )(.*)( netmask.*)/\2/p'
172.16.34.101 

例子3:截取基名

[root@Centos7 data]#echo "/etc/sysconfig/network-scripts/" | sed -r 's#(^.*/)([^/]+/?)#\2#'
network-scripts/

截取目錄名

#echo /etc/rc.d/init.d/functions | sed -rn 's#(/.*/)[[:alnum:]]+/?#\1#p'

例子4:非#開頭的,加上#

[root@Centos7 data]#sed -r '/^[^#]/s/(.*)/#\1/' /etc/fstab 
[root@Centos7 data]#sed -r '/^[^#]/s/(.*)/#&/' /etc/fstab 

例子5:轉成大寫字母 \u:大寫,\l:小寫

[root@Centos7 data]#sed -r '/^[^#]/s/[[:alpha:]]/\u&/g' /etc/fstab 

例子6:獲取主版本號

[root@Centos7 data]#cat /etc/redhat-release | sed -r 's/(^.* )([[:digit:]]+)(.*)/\2/'
7

5.練習


sed示例

sed ‘2p’ /etc/passwd
sed –n ‘2p’ /etc/passwd
sed –n ‘1,4p’ /etc/passwd
sed –n ‘/root/p’ /etc/passwd
sed –n ‘2,/root/p’ /etc/passwd 從2行開始
sed -n ‘/^$/=’ file 顯示空行行號
sed –n –e ‘/^$/p’ –e ‘/^$/=’ file
sed ‘/root/a\superman’ /etc/passwd行後
sed -n '/root/p;/root/a\superman' /etc/passwd
sed ‘/root/i\superman’ /etc/passwd 行前
sed ‘/root/c\superman’ /etc/passwd 代替行
sed ‘/^$/d’ file
sed ‘1,10d’ file
nl /etc/passwd | sed ‘2,5d’
nl /etc/passwd | sed ‘2a tea’
sed 's/test/mytest/g' example
sed –n ‘s/root/&superman/p’ /etc/passwd 單詞後
sed –n ‘s/root/superman&/p’ /etc/passwd 單詞前
sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
sed –i.bak ‘s/dog/cat/g’ pets
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章