天天看點

三劍客: sed

1. 介紹

sed指令: 字元流編輯器。常見的行為機關的檔案編輯器。

sed指令的作用: 擅長對行進行操作

對檔案進行修改調整。

其實等同于vi的作用。隻是它跟檔案本身的互動不太多了。不需要在螢幕上打開檔案。

文法格式

sed 參數 條件-處理 檔案

準備個測試的資料文檔

vi person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian      

2. 檢視

  1. 将帶有zhengzhou的行列印出來
sed -n '/zhengzhou/p' person.txt 
2,henan,zhengzhou
-n 抑制記憶體内資料的輸出,隻列印比對的行。 
p 放在最後 等同于print
// 代表比對中間的内容
不加-n 則如下 比對的行會列印兩次
sed '/zhengzhou/p' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian      
  1. 列印從zhejiang到hebei的行。
sed -n  '/zhejiang/,/hebei/p' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai      

但是 如果把測試文檔改一下,改成這樣

1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

sed -n  '/zhejiang/,/hebei/p' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai      

輸出的結果依然是一樣的。 這就涉及到了,sed的比對機制。

sed 預設會從上往下開始比對,當找到了第一個hebei的時候,它就會認為,任務已經完成了,就會傳回相關的内容。

  1. 列印帶有zhejiang和hebei的行。

和2不太一樣,2是從..到..。 3 是和。

sed]# sed -n  '/zhejiang/p;/hebei/p' person.txt
1,zhejiang,hangzhou
3,hebei,xingtai
6,hebei,xingtai

sed指令的執行過程
條件-執行 條件-執行, 是以需要打兩個P 。 分号作用約等于 |      
  1. 列印第三行
sed]# sed -n '3p' person.txt 
3,hebei,xingtai      
  1. 列印以3開頭的行
sed]# sed -n '/^3/p' person.txt 
3,hebei,xingtai      
  1. 列印文本的最後一行
sed]# sed -n '$p' person.txt 
6,hebei,xingtai      

3. 添加

  1. 在第一行 插入 7,zhejiang,jinhua(或者說 把 7,zhejiang,jinhua 插入到第一行)
sed]# sed  '1i7,zhejiang,jinhua' person.txt 
7,zhejiang,jinhua
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

1: 第一行
i insert i代表插入到某個位置      
  1. 在第一行下面插入7,zhejiang,jinhua (等于插入到第二行)
[root@k8s-vip sed]# sed  '1a7,zhejiang,jinhua' person.txt 
1,zhejiang,hangzhou
7,zhejiang,jinhua
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
[root@k8s-vip sed]# sed  '2i7,zhejiang,jinhua' person.txt 
1,zhejiang,hangzhou
7,zhejiang,jinhua
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai      
  1. 比對帶有henan的行,在行前插入hebei,行下面插入shandong
sed]# sed -e '/henan/ihebei' -e '/henan/ashandong' person.txt 
1,zhejiang,hangzhou
hebei
2,henan,zhengzhou
shandong
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

-e 單個語句内執行多個指令      
  1. 在檔案最下下面插入兩行内容anyang xinxiang
[root@k8s-vip sed]# sed '$aanyang\nxinxinag' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
anyang
xinxinag

$ 末尾
\n 換行符
該方法常用于編寫配置檔案      
  1. 将比對的行寫入到一個新檔案内
[root@k8s-vip sed]# ls
person.txt  person.txt.bak  test.txt
[root@k8s-vip sed]# sed -n '/zhejiang/w 123' person.txt
[root@k8s-vip sed]# ll
總用量 16
-rw-r--r-- 1 root root  20 11月  8 22:25 123
-rw-r--r-- 1 root root 110 11月  8 18:25 person.txt
-rw-r--r-- 1 root root 110 11月  8 18:24 person.txt.bak
-rw-r--r-- 1 root root 106 11月  6 23:47 test.txt
[root@k8s-vip sed]# cat 123
1,zhejiang,hangzhou

w 比對的内容 寫到一個新檔案内
這裡用-n是避免将整個檔案都寫進去
123 新檔案的名字      

4. 删除

  1. 删除檔案中第3行的内容
[root@k8s-vip sed]# sed '3d' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
[root@k8s-vip sed]# cat person.txt  #對比。第三行消失了
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

d delete 删除      
  1. 删除第2行到第5行
[root@k8s-vip sed]# sed '2,5d' person.txt 
1,zhejiang,hangzhou
6,hebei,xingtai
用逗号表示 到      
  1. 删除有hebei的行
[root@k8s-vip sed]# sed '/hebei/d' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
4,shandong,jinan
5,shanxi,xian      
  1. 删除第2行和第6行
[root@k8s-vip sed]# sed  '2d;6d' person.txt 
1,zhejiang,hangzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian      
  1. 比對zhejiang删除zhejiang的下一行
sed]# sed  '/zhejiang/{n;d}' person.txt
1,zhejiang,hangzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5      
  1. 利用sed取消空行輸出
取一個新的文本;
[root@k8s-vip sed]# cat test.txt 
1,zhejiang,hangzhou

2,henan,zhengzhou

3,hebei,xingtai

4,shandong,jinan

5,shanxi,xian

6,hebei,xingtai

[root@k8s-vip sed]# sed '/^$/d' test.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai

^$表示空行
[root@k8s-vip sed]# sed -n '/^$/!p' test.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
!p  !取反      

5. 替換

  1. 将檔案中hebei 替換為 hb
[root@k8s-vip sed]# sed  's#hebei#hb#g' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hb,xingtai
4,shandong,jinan
5,shanxi,xian
6,hb,xingtai

s 代表替換
### 定界符。 也可以用 @@@ ///等來代替
g 代表比對所有。不寫則隻替換每行比對到的第一處      
  1. 把10.0.0.5改為10.0.0.6
改下文本
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
5,shanxi,xian
6,hebei,xingtai
10.0.0.5

[root@k8s-vip sed]# sed -r  's#(.*)5#\16#g' person.txt 
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
(.*) 用于比對 10.0.0.
\1 表示引用上個括号的内容
-r 引用正則      
  1. 把2開頭的行,換為 123qwe
sed]# sed  '/^2/c 123qwe' person.txt
1,zhejiang,hangzhou
123qwe
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5
c 代表整行替換      
  1. 把第2到第4行進行注釋
[root@k8s-vip sed]# sed '2,4s@^@#@g' person.txt
1,zhejiang,hangzhou
#2,henan,zhengzhou
#3,hebei,xingtai
#4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.5

sed]# sed '2,4s@^@#&@g' person.txt
1,zhejiang,hangzhou
#2,henan,zhengzhou
#3,hebei,xingtai
#4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
^ 比對所有# 不知道為啥,反正能這麼用
& 代表前面比對到的内容。 配合 ^$可在比對到的内容前後添加内容      

6. 模式空間和暫存空間

h  模式空間的内容,重定向到暫存空間
H  模式空間的内容,追加到暫存空間
g  暫存空間的内容,複制到模式空間,會覆寫原因内容
G  暫存空間的内容,複制到模式空間,追加至原内容後面      
  1. 将帶有浙江的行,覆寫掉最後一行
sed]# sed '/zhejiang/h;$g' person.txt
1,zhejiang,hangzhou
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
1,zhejiang,hangzhou      
  1. 将帶有浙江的行,覆寫掉最後一行。并将其在檔案中删除
sed]# sed '/zhejiang/{h;d};$g' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
1,zhejiang,hangzhou      
  1. 将帶有浙江的行,追加到最後一行。并将其在檔案中删除
sed]# sed '/zhejiang/{h;d};$G' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6
1,zhejiang,hangzhou      
sed]# sed '/zhejiang/{H;d};$G' person.txt
2,henan,zhengzhou
3,hebei,xingtai
4,shandong,jinan
6,shanxi,xian
6,hebei,xingtai
10.0.0.6

1,zhejiang,hangzhou

暫存空間中。預設有個空行的,是以一般用小h而不是大h      

7. 補充

  1. 以上提到的都是在模式空間内進行的修改。并沒有真的儲存在檔案裡
  2. 使用 -i 參數,可以真實的儲存在記憶體中。 但為了安全 一般用。i.bak 自動生成一個備份檔案
  3. -i 參數一定要用到最後。例如 -ri
  4. 引号的差別
雙引号:把雙引号的内容輸出出來;如果内容中有指令,變量等,會先把指令,變量解析出結果,然後再輸出最終内容來。雙引号内指令或變量的寫法為`指令或變量`或$(指令或變量)
單引号:所見即所得,将單引号内的内容原樣輸出,阻止所有字元的轉義
不加引号:不會将含有空格的字元串視為一個整體輸出,如果内容中有指令,變量等,會先把指令,變量解析出結果,然後再輸出最終内容來,如果字元串含有空格等特殊字元,則不能完整輸出,則需改加雙引号。
倒引号(反引号Esc鍵下方):進行指令的替換,在倒引号内部的shell指令将會被執行,其結果輸出代替用倒引号括起來的文本。