目錄
處理流程
sed(流處理編輯器),處理文本的過程如下:
1、從文本或者管道中讀入一行內容到模式空間(臨時緩沖區)
2、使用sed命令處理,重復第1步,直到文件處理完畢
3、輸出到屏幕
注意兩點:
1、sed一次處理一行的內容
2、sed默認的不改變文件內容
測試數據
[root@localhost test]# cat -n data.txt 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch
使用sed的格式
命令行格式:將包含sed的命令寫在命令行中執行
$ sed [options] 'command' files
腳本格式:將sed的命令寫在一個腳本中,然后執行的時候,指定sed腳本的路徑即可
$ sed -f scriptfile files
上面這兩個命令中,files都是要進行處理的文件。
命令行格式
$sed [options] 'command' files
options可以使用下面這幾個值:
-e:可以指定多個command
-n:與p(print)命令合用時,表示只顯示被選中的行,而不是顯示所有的行,然后被選中的行會顯示兩次。
-i:將sed的操作結果更新到文件中,因為默認的是不會操作文件本身的。
command:行定位(正則)+ sed命令,首先會通過正則行定位,選中要進行操作的行,然后執行sed命令
行定位
選擇1行,可以使用兩種方式:
1、n; 選中1行,n表示行號
2、/pattern/ 使用正則表達式,注意要包含在/..../之間
[root@localhost test]# #打印第5行 [root@localhost test]# sed -n "5 p" data.txt Maecheal 男 30 Washington America [root@localhost test]# #打印匹配"China"的記錄 [root@localhost test]# sed -n "/china/ p" data.txt [root@localhost test]# sed -n "/China/ p" data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China
選擇多行,同樣有兩種方式:
1、x,y; 選中行號在x~y之間的行
2、/pattern1/, /pattern2/ 選擇匹配兩個正則表達式之間的行
[root@localhost test]# #打印第3~6行 [root@localhost test]# cat -n data.txt | sed -n "3,6 p" 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan [root@localhost test]# #打印“Jane”的行,到“貝爺”之間的行 [root@localhost test]# sed -n "/Jane/, /貝爺/ p" data.txt Jane 女 29 Los Angeles America Maecheal 男 30 Washington America 山本 男 25 Nagasaki Japan 村上春樹 男 40 Hiroshima Japan 貝爺 男 35 Paris Franch
不選擇某一行或者某幾行
在后面加 ! 即可
[root@localhost test]# #打印除了第4行以外的所有行 [root@localhost test]# cat -n data.txt | sed -n "4! p" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #打印除3-7行之外的行 [root@localhost test]# cat -n data.txt | sed -n "3,7! p" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 8 貝爺 男 35 Paris Franch
間隔幾行選擇
使用x~y格式,首先打印第x行,然后每個y行,就打印一次
[root@localhost test]# #打印第3行,之后,每隔2行,就打印一次 [root@localhost test]# cat -n data.txt | sed -n "3~2 p" 3 花花 女 30 HeBei China 5 Maecheal 男 30 Washington America 7 村上春樹 男 40 Hiroshima Japan
操作命令
sed有幾個基本的操作命令,分別是下面幾個:
1、-a (append,添加,在行后追加)
2、-i(insert,插入,在行前插入)
3、-d(delete,刪除行)
4、-c(chage,替換)
5、-s(subsitute,替換)
-a 增加行
[root@localhost test]# #在第3行后面增加一行“---------------” [root@localhost test]# cat -n data.txt | sed "3a -------------" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China ------------- 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #在3~5行的每一行后面加一行“==========” [root@localhost test]# cat -n data.txt | sed "3,5a ==========" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China ========== 4 Jane 女 29 Los Angeles America ========== 5 Maecheal 男 30 Washington America ========== 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #在每一行后面增加一行“===========” [root@localhost test]# cat -n data.txt | sed "a ==========" 1 小紅 女 20 BeiJing China ========== 2 小明 男 22 ChongQing China ========== 3 花花 女 30 HeBei China ========== 4 Jane 女 29 Los Angeles America ========== 5 Maecheal 男 30 Washington America ========== 6 山本 男 25 Nagasaki Japan ========== 7 村上春樹 男 40 Hiroshima Japan ========== 8 貝爺 男 35 Paris Franch ========== [root@localhost test]# #在行末增加一行“-------------------” [root@localhost test]# sed '$a -------------------------' data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China Jane 女 29 Los Angeles America Maecheal 男 30 Washington America 山本 男 25 Nagasaki Japan 村上春樹 男 40 Hiroshima Japan 貝爺 男 35 Paris Franch -------------------------
-i 插入行
-i插入行和增加行的操作一樣,區別是a是在行之后增加,i是在行之前插入
[root@localhost test]# #在第3行之前增加一行“---------------” [root@localhost test]# cat -n data.txt | sed "3i --------------" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China -------------- 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #在第3~5行的每一行之前插入一行"===========" [root@localhost test]# cat -n data.txt | sed "3,5i ===========" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China =========== 3 花花 女 30 HeBei China =========== 4 Jane 女 29 Los Angeles America =========== 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #在每一行之前插入一行"===========" [root@localhost test]# cat -n data.txt | sed "i ===========" =========== 1 小紅 女 20 BeiJing China =========== 2 小明 男 22 ChongQing China =========== 3 花花 女 30 HeBei China =========== 4 Jane 女 29 Los Angeles America =========== 5 Maecheal 男 30 Washington America =========== 6 山本 男 25 Nagasaki Japan =========== 7 村上春樹 男 40 Hiroshima Japan =========== 8 貝爺 男 35 Paris Franch
-c 替換行
替換行,是指,將指定行,整行內容都替換為指定內容,注意-s是指替換行中的一部分內容。
注意,區間替換的時候,是整體替換,而不是逐行替換。
[root@localhost test]# #將第2行替換為"hello shell" [root@localhost test]# cat -n data.txt | sed "2c hello world" 1 小紅 女 20 BeiJing China hello world 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #嘗試將第2~5行的每一行都替換為"hello world",但是實際操作后會將2-5行整體替換 [root@localhost test]# cat -n data.txt | sed "2,5c hello world" 1 小紅 女 20 BeiJing China hello world 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #將每一行都替換為“hello world” [root@localhost test]# cat -n data.txt | sed "c hello world" hello world hello world hello world hello world hello world hello world hello world hello world
-d 刪除行
[root@localhost test]# #刪除第4行 [root@localhost test]# cat -n data.txt | sed "4d" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #刪除第4-6行 [root@localhost test]# cat -n data.txt | sed "4,6d" 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# #刪除所有行(無意義) [root@localhost test]# cat -n data.txt | sed "d"
-s 替換行的部分內容
[root@localhost test]# #將字符a替換為X [root@localhost test]# sed 's/a/X/' data.txt 小紅 女 20 BeiJing ChinX 小明 男 22 ChongQing ChinX 花花 女 30 HeBei ChinX JXne 女 29 Los Angeles America MXecheal 男 30 Washington America 山本 男 25 NXgasaki Japan 村上春樹 男 40 HiroshimX Japan 貝爺 男 35 PXris Franch
注意,在替換的時候,只替換了一次,即只替換第一個匹配的內容。如果要將滿足條件的內容都替換,就需要加上g
[root@localhost test]# sed 's/a/X/g' data.txt 小紅 女 20 BeiJing ChinX 小明 男 22 ChongQing ChinX 花花 女 30 HeBei ChinX JXne 女 29 Los Angeles AmericX MXecheXl 男 30 WXshington AmericX 山本 男 25 NXgXsXki JXpXn 村上春樹 男 40 HiroshimX JXpXn 貝爺 男 35 PXris FrXnch
sed使用案例
1、在data文件的第8行下面增加一行“hello world”,並且hello world前面要有4個空格
[root@localhost test]# #測試1,直接輸入4個空格,失敗 [root@localhost test]# sed '8 a hello world' data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China Jane 女 29 Los Angeles America Maecheal 男 30 Washington America 山本 男 25 Nagasaki Japan 村上春樹 男 40 Hiroshima Japan 貝爺 男 35 Paris Franch hello world [root@localhost test]# #測試2,使用反斜線轉義,成功 [root@localhost test]# sed '8 a \ hello world' data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China Jane 女 29 Los Angeles America Maecheal 男 30 Washington America 山本 男 25 Nagasaki Japan 村上春樹 男 40 Hiroshima Japan 貝爺 男 35 Paris Franch hello world
2、刪除demo.txt文件中的空行
[root@localhost test]# cat demo.txt 111111 22222 333333 44444 [root@localhost test]# sed '/^$/ d' demo.txt 111111 22222 333333 44444
3、獲取eth0網卡的ip
[root@localhost test]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:0C:29:21:0C:0F inet addr:192.168.228.153 Bcast:192.168.228.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe21:c0f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:27644 errors:0 dropped:0 overruns:0 frame:0 TX packets:14175 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:22947297 (21.8 MiB) TX bytes:1135056 (1.0 MiB) [root@localhost test]# ifconfig eth0 | sed -n '/inet addr:/ p' inet addr:192.168.228.153 Bcast:192.168.228.255 Mask:255.255.255.0 [root@localhost test]# ifconfig eth0 | sed -n '/inet addr:/ p' | sed 's/.*inet addr://' 192.168.228.153 Bcast:192.168.228.255 Mask:255.255.255.0 [root@localhost test]# ifconfig eth0 | sed -n '/inet addr:/ p' | sed 's/.*inet addr://' | sed 's/B.*$//' 192.168.228.153
高級sed操作
包括以下內容:
1、{command1; command2; command 3}多個sed命令,使用“;”分開
2、n表示跳1行
3、&表示前面已經匹配的字符串內容,反向引用,不用再寫一次正則表達式
多個sed命令
使用花括號{ }將多個sed命令包含在一起,多個sed之間用;分開
[root@localhost test]# cat -n data.txt 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# cat -n data.txt | sed '{3,5 d; s/China/Chinese/}' 1 小紅 女 20 BeiJing Chinese 2 小明 男 22 ChongQing Chinese 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch
跳行
打印奇數行和偶數行
[root@localhost test]# #打印奇數行 [root@localhost test]# cat -n data.txt | sed -n '1~2 p' 1 小紅 女 20 BeiJing China 3 花花 女 30 HeBei China 5 Maecheal 男 30 Washington America 7 村上春樹 男 40 Hiroshima Japan [root@localhost test]# cat -n data.txt | sed -n '{p; n}' 1 小紅 女 20 BeiJing China 3 花花 女 30 HeBei China 5 Maecheal 男 30 Washington America 7 村上春樹 男 40 Hiroshima Japan [root@localhost test]# [root@localhost test]# #打印偶數行 [root@localhost test]# cat -n data.txt | sed -n '2~2 p' 2 小明 男 22 ChongQing China 4 Jane 女 29 Los Angeles America 6 山本 男 25 Nagasaki Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# cat -n data.txt | sed -n '{n; p}' 2 小明 男 22 ChongQing China 4 Jane 女 29 Los Angeles America 6 山本 男 25 Nagasaki Japan 8 貝爺 男 35 Paris Franch
可以使用多個n來進行跳過
&反向引用
&表示前面已經匹配的字符串內容,反向引用,不用再寫一次正則表達式
在男或者女之前加一個gender單詞
[root@localhost test]# cat -n data.txt | sed 's/[男|女]/gender:[男|女]/' 1 小紅 gender:[男|女] 20 BeiJing China 2 小明 gender:[男|女] 22 ChongQing China 3 花花 gender:[男|女] 30 HeBei China 4 Jane gender:[男|女] 29 Los Angeles America 5 Maecheal gender:[男|女] 30 Washington America 6 山本 gender:[男|女] 25 Nagasaki Japan 7 村上春樹 gender:[男|女] 40 Hiroshima Japan 8 貝爺 gender:[男|女] 35 Paris Franch [root@localhost test]# cat -n data.txt | sed 's/[男|女]/gender:&/' 1 小紅 gender:女 20 BeiJing China 2 小明 gender:男 22 ChongQing China 3 花花 gender:女 30 HeBei China 4 Jane gender:女 29 Los Angeles America 5 Maecheal gender:男 30 Washington America 6 山本 gender:男 25 Nagasaki Japan 7 村上春樹 gender:男 40 Hiroshima Japan 8 貝爺 gender:男 35 Paris Franch
案例1:將data.txt中的所有字母都變為大寫
[root@localhost test]# cat -n data.txt 1 小紅 女 20 BeiJing China 2 小明 男 22 ChongQing China 3 花花 女 30 HeBei China 4 Jane 女 29 Los Angeles America 5 Maecheal 男 30 Washington America 6 山本 男 25 Nagasaki Japan 7 村上春樹 男 40 Hiroshima Japan 8 貝爺 男 35 Paris Franch [root@localhost test]# cat -n data.txt | sed 's/[A-Z]/\l&/g' 1 小紅 女 20 beijing china 2 小明 男 22 chongqing china 3 花花 女 30 hebei china 4 jane 女 29 los angeles america 5 maecheal 男 30 washington america 6 山本 男 25 nagasaki japan 7 村上春樹 男 40 hiroshima japan 8 貝爺 男 35 paris franch [root@localhost test]# cat -n data.txt | sed 's/[a-z]/\u&/g' 1 小紅 女 20 BEIJING CHINA 2 小明 男 22 CHONGQING CHINA 3 花花 女 30 HEBEI CHINA 4 JANE 女 29 LOS ANGELES AMERICA 5 MAECHEAL 男 30 WASHINGTON AMERICA 6 山本 男 25 NAGASAKI JAPAN 7 村上春樹 男 40 HIROSHIMA JAPAN 8 貝爺 男 35 PARIS FRANCH
-r 復制指定文件插入到匹配行
[root@localhost test]# cat A.txt 111111 222222 333333 [root@localhost test]# cat B.txt AAAAAAA BBBBBBB CCCCCCC
將A.txt中的內容,插入到B.txt的第2行后面
[root@localhost test]# #將A.txt中的內容插入到B.txt中的第2行后面 [root@localhost test]# sed '2 r A.txt' B.txt AAAAAAA BBBBBBB 111111 222222 333333 CCCCCCC [root@localhost test]# #將A.txt中的內容插入到B.txt中包含CCCCCC的行后面 [root@localhost test]# sed '/CCCCCC/ r A.txt' B.txt AAAAAAA BBBBBBB CCCCCCC 111111 222222 333333 [root@localhost test]# #將A.txt中的內容插入B.txt中每一行的后面 [root@localhost test]# sed 'r A.txt' B.txt AAAAAAA 111111 222222 333333 BBBBBBB 111111 222222 333333 CCCCCCC 111111 222222 333333
-w 復制匹配行,拷貝到指定文件中
對於A.txt中選中的行,保存到文件B.txt中,會首先清空B.txt的內容,然后將選中的行拷貝出來,再保存到B.txt中。
[root@localhost test]# #將A.txt中的2-4行,寫到C.txt中,注意會先清空C.txt [root@localhost test]# sed '2,4 w C.txt' A.txt 111111 222222 333333 [root@localhost test]# cat C.txt 222222 333333
-q 提前退出sed
sed的處理流程是:從文件中讀入一行,然后sed處理一行,一直到文件結束為止。
使用q,可以讓sed提前結束,不用讀到文件結束。
[root@localhost test]# #打印前3行 [root@localhost test]# sed '3 q' data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China [root@localhost test]# [root@localhost test]# #找到第1個Japan [root@localhost test]# sed '/Japan/ q' data.txt 小紅 女 20 BeiJing China 小明 男 22 ChongQing China 花花 女 30 HeBei China Jane 女 29 Los Angeles America Maecheal 男 30 Washington America 山本 男 25 Nagasaki Japan
\( \)多次反向引用
使用\1,\2,\3....\n表示前面的第n個子表達式
獲取所有用戶,以及用戶的UID和GID
[root@localhost test]# head -5 /etc/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 adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@localhost test]# head -5 /etc/passwd | sed 's/^\([a-zA-Z_-]\+\):x:\([0-9]\+\):\([0-9]\+\):.*/USER:\1 \t UID:\2 GID:\3/' USER:root UID:0 GID:0 USER:bin UID:1 GID:1 USER:daemon UID:2 GID:2 USER:adm UID:3 GID:4 USER:lp UID:4 GID:7
獲取eth0的ip地址
[root@localhost test]# ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:0C:29:21:0C:0F inet addr:192.168.228.153 Bcast:192.168.228.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe21:c0f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:34864 errors:0 dropped:0 overruns:0 frame:0 TX packets:17848 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:23505959 (22.4 MiB) TX bytes:1547380 (1.4 MiB) [root@localhost test]# ifconfig eth0 | sed -n '/inet addr/ p' | sed 's/.*inet addr:\([0-9.]\+\).*/\1/' 192.168.228.153