上古神器 sed 教程詳解,小白也能看得懂

介紹


熟悉 Linux 的同學一定知道大名鼎鼎的 Linux 三劍客,它們是 grepawksed,我們今天要聊的主角就是 sed

sed 全名叫 stream editor,流編輯器,用程序的方式來編輯文本,與 vim 的交互式編輯方式截然不同。它的功能十分強大,加上正則表達式的支持,可以進行大量的複雜文本的編輯操作。

實際上 sed 提供的功能非常複雜,有專門的書籍講解它。本文不會講 sed 的全部東西,只會從 sed 的工作原理、常見使用方法等方面進行說明和講解,同時也會給出大量的實踐用例來幫助更好的理解 sed 基本用法。文中的知識點真正掌握後,足以應付平時工作中的基本需求。

它有自己的使用場景:

工作原理

sed 作爲一種非交互式編輯器,它使用預先設定好的編輯指令對輸入的文本進行編輯,完成之後輸出編輯結果。

簡單描述 sed 工作原理:

這樣不斷重複,直到文件末尾,文件內容並沒有改變,除非你使用重定向輸出或指定了 i 參數

正則表達式

sed 基本上就是在玩正則表達式模式匹配,所以,會玩 sed 的人,正則表達式能力一般都比較強。正則表達式內容相對較多,本節不會重點講解正則表達式。

爲了能夠讓大部分朋友比較輕鬆地學習本文知識,這裏還是簡單介紹下正則表達式的基本內容。如果是專門做正則編程開發的,可以去買本正則的書籍來看。

(一)基本正則表達式

(二)擴展正則表達式

擴展正則表達式使用頻率上沒有基本表達式那麼高,但依然很重要,很多情況下沒有擴展正則是搞不定的,sed 命令使用擴展正則時需要加上選項 -r

基本語法

先介紹下 sed 的基本語法。

sed [選項] 'command' filename

選項部分,常見選項包括:-n-e-i-f-r 等。

command 子命令格式:

[地址1, 地址2] [函數] [參數(標記)]

選項簡單說明:

數字定址和正則定址

默認情況下 sed 會對每一行內容進行匹配、處理、輸出,有時候我們不需要對所有內容進行操作,只需要修改一種一部分,比如 1-10 行,偶數行,或包括 hello 字符串的行。

這種情況下,就需要我們去定位特定的行來進行處理,而不是全部內容,這裏把定位指定的行叫做 定址

(一)數字定址

數字定址其實就是通過數字去指定要操作的行,有幾種方式,每種方式都有不同的應用場景。

 1# 只將第4行中hello替換爲A
 2$ sed '4s/hello/A/g' file.txt
 3# 將第2-4行中hello替換爲A
 4$ sed '2,4s/hello/A/g' file.txt
 5# 從第2行開始,往下數4行,也就是2-6行
 6$ sed '2,+4s/hello/A/g' file.txt
 7# 將最後1行中hello替換爲A
 8$ sed '$s/hello/A/g' file.txt
 9# 除了第1行,其它行將hello替換爲A
10$ sed '1!s/hello/A/g' file.txt
11
12

(二)正則定址

正則定址,是通過正則表達式的匹配來確定需要處理編輯哪些行,其它行就不需要處理

1# 將匹配到hello的行執行刪除操作,d 表示刪除
2$ sed '/hello/d' file.txt
3# 刪除空行,"^$" 表示空行
4$ sed '/^$/d' file.txt
5# 將匹配到以ts開頭的行到以te開頭的行之間所有行進行刪除
6$ sed '/^ts/,/^te/d' file.txt
7
8

(三)數字定址和正則定址混用

數字定址和正則定址可以配合使用

1# 匹配從第1行到ts開頭的行,把匹配的行執行刪除
2$ sed '1,/^ts/d' file.txt
3
4

基本子命令

(一)替換子命令 s

子命令 s 爲替換子命令,是平時 sed 使用最多的命令,因爲支持正則表達式,功能很強大,基本可以替代 grep 的基本用法。

基本語法:

[address]s/pat/rep/flags

替換子命令基本用法

 1# 將每行的hello替換爲HELLO,只替換匹配到的第一個
 2$ sed 's/hello/HELLO/' file.txt
 3# 將匹配到的hello全部替換爲HELLO,g表示替換一行所有匹配到的
 4$ sed 's/hello/HELLO/g' file.txt
 5# 將第2次匹配到的hello替換
 6$ sed 's/hello/A/2' file.txt
 7# 將第2次後匹配到的所有都替換
 8$ sed 's/hello/A/2g' file.txt
 9# 在行首加#號
10$ sed 's/^/#/g' file.txt
11# 在行尾加東西
12$ sed 's/$/xxx/g' file.txt
13
14

正則表達式的簡單使用

1# 使用擴展正則表達式,結果爲:A
2$ echo "hello 123 world" | sed -r 's/[a-z]+ [0-9]+ [a-z]+/A/'
3
4# <b>This</b> is what <span style="x">I</span> meant
5# 要求:去掉上述html文件中的tags
6$ sed 's/<[^>]*>//g' file.txt
7
8

多個匹配

1# 將1-3行的my替換爲your,且3行以後的This替換爲That
2$ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
3# 等價於
4$ sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt
5
6

使用匹配到的變量

1# 將匹配到的字符串前後加雙引號,結果爲:My "name" chopin
2# "&"表示匹配到的整個結果集
3$ echo "My name chopin" | sed 's/name/"&"/'
4
5# 如下命令,結果爲:hello=world,"\1"和"\2"表示圓括號匹配到的值
6$ echo "hello,123,world" | sed 's/\([^,]\),.*,\(.*\)/\1=\2/'
7
8

其它幾個常見用法

 1# 只將修改匹配到行內容打印出來,-n關閉了模式空間的打印模式
 2$ sed -n 's/i/A/p' file.txt
 3
 4# 替換是忽略大小寫,將大小寫i替換爲A
 5$ sed -n 's/i/A/i' file.txt
 6
 7# 將替換後的內容另存爲一個文件
 8$ sed -n 's/i/A/w b.txt' file.txt
 9$ sed -n 's/i/A/' file.txt > b.txt
10
11

注意,sed 修改匹配到的內容後,默認行爲是不保存到原文件,直接輸出修改後模式空間的內容,如果要修改原文件需要指定 -i 選項。

(二)追加行子命令 a

子命令 a 表示在指定行下邊插入指定的內容行;

1# 將所有行下邊都添加一行內容A
2$ sed 'a A' file.txt
3# 將文件中1-2行下邊都添加一行內容A
4$ sed '1,2a A' file.txt
5
6

(三)插入行子命令 i

子命令 ia 使用基本一樣,只不過是在指定行上邊插入指定的內容行

1# 將文件中1-2行上邊都添加一行內容A
2$ sed '1,2i A'
3
4

(四)替換行子命令 c

子命令 c 是表示把指定的行內容替換爲自己需要的行內容

1# 將文件所有行都分別替換爲A
2$ sed 'c A' file.txt
3# 將文件中1-2行內容替換爲A,注意:兩行內容變成了一行A
4$ sed '1,2c A' file.txt
5# 將1-2行內容分別替換爲A行內容
6$ sed '1,2c A\nA' file.txt
7
8

(五)刪除行子命令 d

子命令 d 表示刪除指定的內容行,這個很容理解

1# 將文件中1-3行內容刪除
2$ sed '1,3d' file.txt
3# 將文件中This開頭的行內容刪除
4$ sed '/^This/d' file.txt
5
6

(六)設置行號子命令 =

子命令 =,可以將行號打印出來

1# 將指定行上邊顯示行號
2$ sed '1,2=' file.txt
3# 可以將行號設置在行首
4$ sed '=' file.txt | sed 'N;s/\n/\t/'
5
6

(七)子命令 N

子命令 N,把下一行內容納入當緩存區做匹配,注意的是第一行的 \n 仍然保留

其實就是當前行的下一行內容也讀進緩存區,一起做匹配和修改,舉個例子吧

1# 將偶數行內容合併到奇數行
2$ sed 'N;s/\n//' file.txt
3
4

哈哈,是不是很簡單?

實戰練習

掌握了上邊的基礎命令操作後,基本上可以滿足平時 95% 的需求啦。sed 還有一些高級概念,比如:模式空間、保持空間、高級子命令、分支和測試等,平時使用概率非常小,本文就暫不講解了,有需要的同學可以私信我一起交流學習哈。

學習了這麼多基礎用法後,只要你勤加練習,多實踐,多使用,一定可以得心應手,極大提高的文本處理效率。下邊我簡單再給出一些比較實用的操作實踐,希望對大家有幫助。

1. 刪除文件每行的第二個字符

1$ sed -r 's/(.)(.)(.*)$/\1\3/' file.txt
2
3

2. 交換每行的第一個字符和第二個字符

1$ sed -r ‘s/(.)(.)(.*)/\2\1\3/’ file.txt
2
3

3. 刪除文件中所有的數字

1$ sed 's/[0-9]//g' file.txt
2
3

4. 用製表符替換文件中出現的所有空格

1$ sed -r 's/ +/\t/g' file.txt
2
3

5. 把所有大寫字母用括號 () 括起來

1$ sed -r 's/([A-Z])/(\1)/g'
2
3

6. 隔行刪除

1$ sed '0~2{d}' file.txt
2
3

7. 刪除所有空白行

1$ sed '/^$/d' file.txt
2
3

好了,以上是 sed 命令常用的全部內容。想要熟練掌握,只有多實踐,多練習正則表達式的使用,一旦熟練掌握後,相信在日後工作中一定會產生巨大作用的。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cZ1zPxqTlJLoBdsVxb8rNQ