linux系統命sed詳解

目錄

命令介紹

sed能同時處理多個文件多行的內容

sed是一個很好的文件處理工具,本身是一個管道命令。能同時處理多個文件多行的內容,可以不對原文件改動,把整個文件匹配的數據內容選取之後再輸入到屏幕,可以把只匹配到模式的內容輸入到屏幕上。還可以對原文件數據內容行進行替換、刪除、新增等特定工作改動,但是不會再屏幕上返回結果。

sed命令格式

sed 參數 ‘command’ 源文件(s)
sed 參數 -f scriptfile 源文件(s)

sed 命令參數
  1. -h或–help:顯示幫助;
  2. -V或–version:顯示版本信息;
  3. -n或–quiet或——silent∶使用安靜(silent)模式。在一般 sed 的用法中,所有來自 STDIN的資料一般都會被列出到屏幕上。但如果加上 -n 參數後,則只有經過sed 特殊處理的那一行(或者動作)纔會被列出來;
  4. -e或–expression=<script>∶直接在命令行模式上進行sed動作編輯,此爲默認選項;
  5. -f<script文件>或–file=<script文件>∶以選項中指定的script文件中的格式來處理輸入的文本文件;
  6. -r∶sed 的動作支援的是延伸型正規表示法的語法。(預設是基礎正規表示法語法)
  7. -i∶直接修改讀取文件的內容,而不在屏幕輸出。
sed標記參數(就是前面沒有-的參數)也可以稱之爲編輯器

a∶在定位行後新增內容, a 的後面可以接字符串,而這些字符串會在新的一行出現(當前行的下一行);
c∶用新文本替換定位文本, c 的後面可以接字符串,這些字符串可以取代 n1,n2 之間的行;
d∶刪除定位行,因爲是刪除啊,所以 d 後面通常不接任何咚咚;
g∶表示行內全面替換。 --global
i∶在定位行前插入新內容, i 的後面可以接字符串,而這些字符串會在新的一行出現(當前行的上一行);
I∶還是| 顯示與八進制ACSII代碼等價的控制符;
n∶從另一個文件中讀文本下一行,並從下一條命令而不是第一條命令開始對其的處理;
N∶在數據流中添加下一行以創建用於處理的多行組;
p∶列印,亦即將某個選擇的資料印出。通常 p 會與參數 sed -n 一起運作;
q∶第一個模式匹配完成後退出或立即退出;
r∶後面接filename,表示從另一個文件中讀文本,類似輸入重定向 <
s∶使用指定模式去替換匹配到模式,可以直接進行取代的工作!通常這個 s 的動作可以搭配正規表達式!例如 1,20s/old/new/g;
w∶後面接filename,表示把行寫入一個文件;
x ∶表示互換模板塊中的文本和緩衝區中的文本;
y ∶表示把一個字符翻譯爲另外的字符(但是不用於正則表達式)
=∶表示打印行號;
{}∶當用到sed不同的標記參數(就是前面沒有-的參數)時,用大括號{},且不同標記參數之間用分號隔開。

sed行號使用方法
# 使用行號,可以是一個簡單數字,或是一個行號範圍
xp 												x爲行號
x,yp											表示行號從x到y
/pattern/p        							查詢包含模式的行
/pattern/,/pattern/	p					查詢包含兩個模式的行
/pattern/,xp 								將匹配到patern的行到在給定行號的所有內容打印出來
x,/pattern/p								通過行號和模式查詢匹配的行
x,y!p											查詢不包含指定行號x和y的行

實例演練及總結 — sed命令匹配行

準備測試文件0

[root@myhost script]# cat /home/script/log2019.log 
2019-01
2019-02
2019-03
2019-04
2019-05
2019-06
2019-07
2019-08
2019-09
2019-10
2019-11
2019-12
標記參數p的打印功能
#之所以會將文件內容每一行打印兩遍是因爲sed沒有參數時是默認會打印文件中的所有行。
[root@myhost script]# sed 'p' /home/script/log2019.log
2019-01
2019-01
2019-02
2019-02
2019-03
2019-03
2019-04
2019-04
2019-05
2019-05
2019-06
2019-06
2019-07
2019-07
2019-08
2019-08
2019-09
2019-09
2019-10
2019-10
2019-11
2019-11
2019-12
2019-12
標記參數p打印指定的行
[root@myhost script]# sed '2p' /home/script/log2019.log
2019-01
2019-02 ==》
2019-02 ==》打印文件的第二行,第二行之所以會打印兩遍是因爲sed默認會打印文件中的所有行。
2019-03
2019-04
2019-05
2019-06
2019-07
2019-08
2019-09
2019-10
2019-11
2019-12
–n參數和標記參數p一起表示只打印匹配的行。
[root@myhost script]#  sed -n 'p'  /home/script/log2019.log  
[root@myhost script]#  cat'  /home/script/log2019.log  
2019-01
2019-02
2019-03
2019-04
2019-05
2019-06
2019-07
2019-08
2019-09
2019-10
2019-11
2019-12

#標記打印文件中的第二行
[root@myhost script]#  sed -n '2p'  /home/script/log2019.log 
2019-02

#標記打印文件中的第一行至第三行
[root@myhost script]#  sed -n '1,3p' /home/script/log2019.log 
2019-01
2019-02
2019-03

#標記打印文件中匹配2019-05字符串的行,匹配的內容需要寫在'/ /'裏面
[root@myhost script]# sed -n '/2019-05/p'  /home/script/log2019.log 
2019-05

#標記打印文件中從開始匹配到02的行到第4行的所有內容;
#但是如果匹配到02所處的行在第4行之後,則僅打印匹配到02的那一行。
[root@myhost script]# sed -n '/02/, 4p'  /home/script/log2019.log 
2019-02
2019-03
2019-04

#標記打印文件中從開始匹配到09的行到第4行的所有內容;
#由於09處於文件中的第9行,則只打印出匹配到09的那一行
[root@myhost script]# sed -n '/09/, 4p' /home/script/log2019.log 
2019-09


#標記打印文件中從開始匹配03的那一行到匹配09的那一行中間所有的內容,是一個範圍
#但是如果匹配到前一個模式所處的行在匹配到後一個模式的行之後,則僅打印匹配到後一個模式的行以及之後的所有內容。
[root@myhost script]# sed -n '/03/, /09/p' /home/script/log2019.log 
2019-03
2019-04
2019-05
2019-06
2019-07
2019-08
2019-09
[root@myhost script]# sed -n '/09/, /03/p' /home/script/log2019.log 
2019-09
2019-10
2019-11
2019-12
[root@myhost script]# sed -n '/08/, /03/p' /home/script/log2019.log 
2019-08
2019-09
2019-10
2019-11
2019-12
行號的打印

當用到sed不同的標記參數(就是前面沒有-的參數)時,可以用大括號{}把所有標記參數括起來,且不同標記參數之間用分號(;)隔開。

#先打印行號,再標記打印行內容
[root@myhost script]#  sed -n '{=;p}' /home/script/log2019.log 
1
2019-01
2
2019-02
3
2019-03
4
2019-04
5
2019-05
6
2019-06
7
2019-07
8
2019-08
9
2019-09
10
2019-10
11
2019-11
12
2019-12

#打印第二行到第四行的內容並先顯示行號
[root@myhost script]#  sed -n '2,4 {=;p}' /home/script/log2019.log 
2
2019-02
3
2019-03
4
2019-04

#打印文件的第1行到第2行的內容,並先打印行號
[root@myhost script]# sed -n '1,2{=;p}' /home/script/log2019.log 
1
2019-01
2
2019-02

#打印文件的非(第1行到第2行)的內容,並先打印行號
[root@myhost script]# sed -n '1,2!{=;p}' /home/script/log2019.log 
3
2019-03
4
2019-04
5
2019-05
6
2019-06
7
2019-07
8
2019-08
9
2019-09
10
2019-10
11
2019-11
12
2019-12

實例演練及總結 — sed命令(擴展)正則表達式

注意:必須結合-r選項使用, 匹配的模式首先都要寫在’/ /'中

正則表達式

在這裏插入圖片描述

準備測試文件1

[root@myhost yuki]# cat /etc/sysconfig/network-scripts/ifcfg-eth0           
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
### BRIDGE MODE ###
IPADDR=10.0.0.25
NETMASK=255.255.255.0
DNS=8.8.8.8
GATEWAY=10.0.0.
### NAT MODE ###
#IPADDR=192.168.22.244
#NETMASK=255.255.255.0
#DNS=8.8.8.8
#DNS=192.168.22.1  
標記參數q:第一個模式匹配完成後退出或立即退出
 #打印前5行
[root@myhost yuki]# sed '5q' /etc/sysconfig/network-scripts/ifcfg-eth0           
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
打印以#開頭的行
[root@myhost yuki]# sed -n '/^#/p' /etc/sysconfig/network-scripts/ifcfg-eth0 
### BRIDGE MODE ###
### NAT MODE ###
#IPADDR=192.168.22.244
#NETMASK=255.255.255.0
#DNS=8.8.8.8
#DNS=192.168.22.1  
打印以非#開頭的行
[root@myhost yuki]# sed -n '/^#/!p' /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=10.0.0.25
NETMASK=255.255.255.0
DNS=8.8.8.8
GATEWAY=10.0.0.
打印以非#開頭的行和非空白行^$
[root@myhost yuki]# sed -n '/^#/!{/^$/!p}' /etc/sysconfig/network-scripts/ifcfg-eth0
[root@myhost yuki]# egrep -v '^#|^$' /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=10.0.0.25
NETMASK=255.255.255.0
DNS=8.8.8.8
GATEWAY=10.0.0.1

準備測試文件2

[root@myhost script]# cat /home/script/mylife.txt 
hello world
hello. linux
how are you?
i am  fine
thanks, and you?
標記參數{}

{}∶當用到sed不同的標記參數(就是前面沒有-的參數)時,用大括號{},且不同標記參數之間用分號隔開。

[root@myhost ~]# sed '/are/{s/are/is/g;s/you/she/g}'  /home/script/mylife.txt 
#hello world
#hello. linux
#how is she?
i am  fine
thanks, and you?
標記參數s + 標記參數g

s:使用指定模式去替換匹配到模式,可以直接進行取代的工作!通常這個 s 的動作可以搭配正規表達式。
g∶表示行內全面替換。 --global

  • 和正則表達式^搭配 ( ^在匹配到的模式所在行行首進行操作)

##### 在匹配到world行進行操作 ##### 
[root@myhost script]# sed '/world/s/^/hi,/g ' /home/script/mylife.txt 
hi,hello world
hello. linux
how are you?
i am  fine
thanks, and you?

##### 在匹配到hello行進行操作 ##### 

#把所有匹配到hello的行中出現的第1次出現的字母l替換成w 
[root@dscq4 ~]# sed '/hello/s/l/w/ ' /home/script/mylife.txt
#hewlo world
#hewlo. linux
#how are you?
i am  fine
thanks, and you?

#把所有匹配到hello的行中出現的第2次出現的字母l替換成w 
[root@dscq4 ~]# sed '/hello/s/l/w/2 ' /home/script/mylife.txt
#helwo world
#helwo. linux
#how are you?
i am  fine
thanks, and you?

#把所有匹配到hello的行中出現的所有字母l替換成w 
[root@myhost ~]# sed '/hello/s/l/w/g ' /home/script/mylife.txt
#hewwo worwd
#hewwo. winux
#how are you?
i am  fine
thanks, and you?


##### 在匹配到hello行進行操作 ##### 
#把所有匹配到hello的行中出現的所有字母l替換成w 並打印2遍
[root@myhost ~]# sed '/hello/s/l/w/2p ' /home/script/mylife.txt
#helwo world
#helwo world
#helwo. linux
#helwo. linux
#how are you?
i am  fine
thanks, and you?

#把所有匹配到hello的行中第2次及第2次之後出現字母l替換成w 
[root@myhost ~]# sed '/hello/s/l/w/2g ' /home/script/mylife.txt
#helwo worwd
#helwo. winux
#how are you?
i am  fine
thanks, and you?
[root@dscq4 ~]# 

##### 在每行進行操作 ##### 
[root@myhost ~]# sed 's/^/Start /g'  /home/script/mylife.txt 
Start hello world
Start hello. linux
Start how are you?
Start i am  fine
Start thanks, and you?

#指定的1-3行,在其行首添加#,一般都用在進行註釋當中
[root@dscq4 ~]# sed '1,3s/^/#/g'  /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
  • 和正則表達式&搭配
    &保存匹配到的模式並用來替換其他字符,如:s/love/22&22/,love這22love22。
[root@myhost script]# sed 's/linux/jie+&/g'  /home/script/mylife.txt 
hello world
hello. jie+linux
how are you?
i am  fine
thanks, and you?

[root@myhost script]# sed 's/linux/&+jie/g'  /home/script/mylife.txt 
hello world
hello. linux+jie
how are you?
i am  fine
thanks, and you?
  • 和正則表達式$搭配( $在匹配到的模式所在行行尾進行操作)
##### 在匹配到are行進行操作 ##### 
[root@myhost script]# sed '/are/s/$/問號/g'  /home/script/mylife.txt 
hello world
hello. linux
how are you?問號
i am  fine
thanks, and you?

##### 在每行進行操作 ##### 
[root@myhost ~]# sed 's/$/ end/g'  /home/script/mylife.txt 
hello world end
hello. linux end
how are you? end
i am  fine end
thanks, and you? end
  • 和正則表達式(模式)搭配,(模式)表示按照此模式將內容進行分組
#在匹配到yo內容所在的行進行操作
#操作:將所有"?" 替換成 "問號"
[root@myhost script]# sed '/you/s/\(?\)/問號/g'  /home/script/mylife.txt 
hello world
hello. linux
how are you問號
i am  fine
thanks, and you問號

#操作:將所有"?" 替換成 "組內容+問號"
[root@myhost script]# sed '/you/s/\(?\)/\1問號/g'  /home/script/mylife.txt 
hello world
hello. linux
how are you?問號
i am  fine
thanks, and you?問號

[root@myhost script]# sed '/you/s/\(?\)/\1\1\1問號/g'  /home/script/mylife.txt 
hello world
hello. linux
how are you???問號
i am  fine
thanks, and you???問號

[root@myhost script]# sed '/you/s/\(.*\)/\1你好嗎/g'  /home/script/mylife.txt 
hello world
hello. linux
how are you?你好嗎
i am  fine
thanks, and you?你好嗎
#.*表示任意字符,\1表示引用第一個分組
#因爲是匹配的任意字符,所以整個行的內容都被分爲一組了,在添加內容的時候就添加到結尾了

[root@myhost script]# sed '/you/s/\(.*\)/你好嗎? \1/g'  /home/script/mylife.txt 
hello world
hello. linux
你好嗎? how are you?
i am  fine
你好嗎? thanks, and you?
標記參數a

a∶在定位行後新增內容, a 的後面可以接字符串,而這些字符串會在新的一行出現(當前行的下一行)

標記參數i

i∶在定位行的前一行插入新內容, i 的後面可以接字符串,而這些字符串會在新的一行出現(當前行的上一行)

[root@myhost  script]# sed '/are/i my name is yuki'  /home/script/mylife.txt 
hello world
hello. linux
my name is yuki  《==
how are you?	《==
i am  fine
thanks, and you?

[root@myhost script]# sed '/are/i\my name is yuki'  /home/script/mylife.txt 
hello world
hello. linux
my name is yuki  《==
how are you?
i am  fine
thanks, and you?

[root@myhost script]# sed '/are/i/my name is yuki'  /home/script/mylife.txt 
hello world
hello. linux
/my name is yuki  《==
how are you?
i am  fine
thanks, and you?
###### 插入多行要用\n來換行 ######
[root@myhost ~]# sed '/are/i my name is yuki what is your name?'  /home/script/mylife.txt 
hello world
hello. linux
my name is yuki what is your name?
how are you?
i am  fine
thanks, and you?

[root@myhost ~]# sed '/are/i my name is yuki\n what is your name?'  /home/script/mylife.txt 
hello world
hello. linux
my name is yuki
 what is your name?
how are you?
i am  fine
thanks, and you?
命令參數-e

-e或–expression=

##### 刪除#開頭的行以及匹配到and字符串的行 ##### 
[root@myhost ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
[root@myhost ~]# sed  -e '/^#/d' -e '/and/d' /home/script/mylife.txt 
i am  fine

[root@myhost ~]# sed '/are/{s/are/is/g;s/you/she/g}'  /home/script/mylife.txt 
#hello world
#hello. linux
#how is she?
i am  fine
thanks, and you?
命令參數-i

-i∶直接修改讀取文件的內容,而不在屏幕輸出。

[root@myhost ~]# cat /home/script/mylife.txt 
hello world
hello. linux
how are you?
i am  fine
thanks, and you?

[root@myhost ~]# sed -i '1,3s/^/#/g'  /home/script/mylife.txt 

[root@myhost ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
標記參數d

d∶刪除定位行,因爲是刪除啊,所以 d 後面通常不接任何咚咚;

##### 刪除#號開始的行 #####
##### 這裏沒有加-i,相當於對文件進行了操作但是最後沒有保存 ##### 
[root@myhost ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
[root@myhost ~]# sed '/^#/d'  /home/script/mylife.txt 
i am  fine
thanks, and you?

##### 刪除非#號開始的行 #####
##### 這裏沒有加-i,相當於對文件進行了操作但是最後沒有保存 ##### 
[root@myhost ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
[root@myhost ~]# sed '/^#/!d'  /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?

##### 刪除文件的第一行,即首行 #####
[root@myhost ~]# sed '1d'  /home/script/mylife.txt 
#hello. linux
#how are you?
i am  fine
thanks, and you?

[root@myhost ~]# sed '^d'  /home/script/mylife.txt 
sed: -e expression #1, char 1: unknown command: `^'

##### 刪除文件的最後一行,即尾行 #####

[root@myhost  ~]# sed '$d'  /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine

##### 刪除文件的1-3行,是範圍 #####
[root@myhost  ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
[root@myhost  ~]# sed '1,3d'  /home/script/mylife.txt 
i am  fine
thanks, and you?

##### 刪除文件匹配到thanks的行 #####
[root@myhost  ~]# sed '/thanks/d' /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine

##### 刪除文件匹配到包含字母o的行 #####
[root@myhost  ~]# sed '/o/d' /home/script/mylife.txt 
i am  fine

##### 刪除文件匹配到單詞you的行,\<\> 作單詞牟定#####

[root@myhost  ~]# sed '/\<you\>/d' /home/script/mylife.txt 
#hello world
#hello. linux
i am  fine

sed引用變量

第1種:當sed命令裏面沒有默認的變量(標記參數)時可以把單引號改成雙引號;
第2種:當sed命令裏面有默認的變量(標記參數)時,那自定義的變量需要加單引號,且sed裏面的匹配語句必須用單引號,以及標記參數也要加$符號

[root@myhost  ~]# cat /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
[root@myhost  ~]# name=yuki

##把匹配linux的字符替換成變量的值
[root@myhost  ~]# sed 's/linux/$name/'  /home/script/mylife.txt   ==單引號無法解析變量的值
#hello world
#hello. $name  《==
#how are you?
i am  fine
thanks, and you?
[root@myhost  ~]# sed "s/linux/$name/"  /home/script/mylife.txt  ==雙引號可以解析變量的值
#hello world
#hello. yuki  《==
#how are you?
i am  fine
thanks, and you?

#$a其實標記參數a
##當sed命令也有默認變量時,在去引用自己定義的變量會出現語法錯誤
[root@myhost  ~]# sed '$a '$name'' /home/script/mylife.txt  
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
yuki  《==

#$i其實標記參數i
##當sed命令也有默認變量時,在去引用自己定義的變量會出現語法錯誤
[root@myhost  ~]# sed '$i '$name'' /home/script/mylife.txt 
#hello world
#hello. linux
#how are you?
i am  fine
yuki
thanks, and you?


[root@myhost  ~]# sed 'i '$name'' /home/script/mylife.txt 
yuki
#hello world
yuki
#hello. linux
yuki
#how are you?
yuki
i am  fine
yuki
thanks, and you?
[root@myhost  ~]# sed 'a '$name'' /home/script/mylife.txt 
#hello world
yuki
#hello. linux
yuki
#how are you?
yuki
i am  fine
yuki
thanks, and you?
yuki

sed的其它高級使用

1)把正在用sed操作的文件內容追加到另外一個文件中
[root@myhost  ~]# sed 's/are/is/w ./test.txt'  /home/script/mylife.txt 
#hello world
#hello. linux
#how is you?
i am  fine
thanks, and you?

[root@myhost  ~]# cat ./test.txt 
#how is you?
[root@dscq4 ~]# 
2)讀取一個文件到正在用sed操作的文件中
#在匹配how的行,讀進來另一個文件的內容,讀進來的文件的內容會插入到匹配Ethernet的行後  
[root@dscq4 ~]# sed '/how/r  /home/script/mylife.txt'  ./test.txt 
#how is you?  《==
#hello world
#hello. linux
#how are you?
i am  fine
thanks, and you?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章