sed 和 gawk 編輯器

2020-08-10 17:43:19

sed 編輯器可以在讀取數據時對數據快遞的進行各種處理操作,s 命令 可以替換文字,i 命令 可以插入文字,a 命令 可以追加文字,c 命令 可以修改文字,d 命令 可以刪除文字,y 命令 可以轉換文字,p 命令 可以列印文字,= 命令 可以列印行號,l 命令 可以列印 ASCII 字元,w 命令 可以輸出內容到指定檔案,r 命令 可以從指定檔案讀取內容。
sed 編輯器還支援 行定址 ,以上大部分命令都支援使用行定址的方式來靈活操作數據。
gawk 編輯器是根據 awk 工具從 Unix 移植到 Linux 的 GNU 版本,雖然功能強大,但 Linux 預設沒有安裝該工具,可以通過 yum install gawk 命令進行安裝。gawk 編輯器提供的是一種程式語言,而不僅僅是編輯器命令。

19.1 文字處理

sed 和 gawk 實現的效果是:不進入互動式編輯器,就可以實現自動格式化、插入、修改或刪除檔案中的文字數據。

19.1.1 sed 編輯器

sed 編輯器簡稱 流編輯器( Stream Editor ) 。可以根據命令來處理數據流中的數據,這些命令可以直接從命令列輸入,也可以存在於指定檔案中。
sed 編輯器會將所有命令與一行數據進行匹配,匹配完畢後就自動讀取下一行數據,並重復之前的操作,當所有數據都讀取完畢後,命名纔會終止。處理後的數據不會影響原檔案,而是輸出到 STDOUT 。
sed 命令的基本格式是 sed option script file 。
option 中可用的選項如下圖:在这里插入图片描述

19.1.1.1 在命令列定義編輯器命令

預設情況下,sed 編輯器會將指定的命令應用到 STDIN 上,這樣就可以直接將數據通過管道輸入到 sed 編輯器中進行處理,效果如下:在这里插入图片描述
在上圖中可以看到,echo 輸出的語句通過 | 管道傳入 sed 命令。在 sed 編輯器中使用了 s 命令,作用是用斜線之間指定的第二個文字替換第一個文字的內容。

19.1.1.2 在命令列使用多個編輯器命令

要在 sed 編輯器的命令列模式中指定多個命令,使用 sed -e 命令即可,效果如下:在这里插入图片描述
在上圖中可以看到,新增 -e 指令後,只需要在多個命令之間使用分號隔開即可。需要注意的是,分號和命令末尾之間不能有空格。
如果不想使用分號,也可以使用 bash shell 的 次提示符 來分隔命令,效果如下:在这里插入图片描述
在這種模式下,不需要在命令末尾新增分號。

19.1.1.3 從檔案中讀取編輯器命令

使用 sed -f 命令即可從檔案中讀取命令,效果如下:在这里插入图片描述
在這種模式下,不需要在命令末尾新增分號。需要注意的是,.sed 後綴並不是強制的,只是爲了避免 sed 編輯器的指令碼檔案和其他檔案混淆。

19.1.2 gawk 編輯器

gawk 編輯器可以提供一個類程式設計環境,讓修改和重新組織檔案中的數據變的更得心應手。
Linux 中預設沒有安裝 gawk 編輯器,如果當前 Linux 中不存在該編輯器,需要使用 yum install gawk 命令進行安裝。
使用 yum info gawk 命令可以檢視該編輯器的詳細資訊,源:installed 表示該編輯器已經安裝到當前 Linux 中。在这里插入图片描述
也可以使用 whereis gawk 命令來檢視當前 Linux 中是否存在該編輯器。在这里插入图片描述
gawk 編輯器是 Unix 中 awk 編輯器的 GNU 版本,該編輯器提供的是一種程式語言,而不僅僅是編輯器命令。
gawk 編輯器的強大之處在於可以編寫指令碼,通過指令碼來讀取文字行的數據,對數據進行處理後再顯示數據,以及建立任意型別的輸出報告。

19.1.2.1 gawk 命令格式

gawk 編輯器的基本格式是 gawk option ‘{program}’ file ,編輯器指令碼必須使用單引號和花括號包裹。
option 中可用的選項如下圖:在这里插入图片描述

19.1.2.2 從命令列讀取指令碼

預設情況下,gawk 編輯器從 STDIN 中接收數據,效果如下:在这里插入图片描述
當 gawk 命令接收到通過管道傳入的 echo 命令的輸出後,就在控制檯列印了 Hello World 語句。
如果直接在命令列中執行 gawk 命令,那麼該命令會一直等待使用者輸入,效果如下:在这里插入图片描述
從上圖中可以看到,第一次執行 gawk 命令後,手動輸入 1 並回車,控制檯列印了 Hello World 語句,再次輸入 2 並回車,控制檯再次列印了 Hello World ,以此類推。只要不手動退出,gawk 編輯器會一直監聽使用者輸入。
在第一次執行 gawk 命令的最後,可以清楚看到是使用 Ctrl + C 強制退出了 gawk 編輯器。其實該編輯器本身支援使用 Ctrl + D 退出監聽,可以看到,第二次執行 gawk 命令的最後,編輯器退出後並沒有顯示 Ctrl + C 的按鍵痕跡,因爲這裏正確使用了 Ctrl + D 來退出 gawk 編輯器。

19.1.2.3 使用數據欄位變數

gawk 編輯器在處理檔案數據時,會自動爲 被欄位分隔符分隔後的每個數據 分配一個變數,規則如下:
$0 表示整個文字行
$1 表示第一個數據欄位
$2 表示第二個數據欄位
以此類推
gawk 預設的 欄位分隔符 是 任意的空白字元 ,例如空格或製表符,效果如下在这里插入图片描述

從上圖中可以看到,每行數據中存在一個空格,通過該空格將每行的數據分爲兩部分,gawk 編輯器使用 $1 成功獲取到每行的第一部分,並將其輸出。
可以使用 gawk -F 來修改欄位分隔符,效果如下:在这里插入图片描述
上圖中使用 gawk -F : 命令將欄位分隔符替換成了冒號,然後輸出了 passwd 檔案中每行的第一個欄位。由於輸出內容過多,將輸出內容通過管道傳入 tail -n 5 命令,最後只輸出 5 行數據。

19.1.2.4 在指令碼中使用多個命令

gawk 編輯器允許將多個命令組合成一個完整的編輯器,和 sed 編輯器類似,對於多命令使用分號分隔即可,效果如下:在这里插入图片描述
從上圖中可以看到,gawk 編輯器先將第三個欄位改爲 not is ,再使用 print $0 命令將整行數據輸出。
同樣的,也支援使用 次提示符 來編寫多個命令,效果如下:在这里插入图片描述

19.1.2.5 從檔案中讀取指令碼

gawk 編輯器允許將指令碼儲存到檔案中,效果如下:在这里插入图片描述
從上圖中可以看到,在指令碼中編寫多個命令非常方便,同時指令碼命令外只需要使用花括號進行包裹,不再需要使用單引號

19.1.2.6 在處理數據之前執行指令碼

gawk 編輯器可以控制指令碼命令的執行時機。預設情況下,指令碼命令會在讀取一行文字後就自動執行一次。但可以通過 BEGIN 關鍵字 強制 gawk 在讀取數據之前執行指定指令碼。 ,效果如下:在这里插入图片描述
從上圖中可以看到,預設情況下,gawk 命令會在監聽到使用者輸入後再輸出 Hello World 。但當使用 BEGIN 關鍵字後,gawk 命令直接就輸出了 Hello World ,不再等待使用者輸入。
通過這種方式,可以爲輸出內容準備一個通用的顯示頭資訊,效果如下:在这里插入图片描述

19.1.2.7 在處理數據後執行指令碼

使用 END 關鍵字可以強制 gawk 在讀取數據結束之後執行指定指令碼,效果如下:在这里插入图片描述

19.1.2.8 通過 FS 變數指定欄位分隔符

如果是在檔案中編寫指令碼,可以使用特殊變數 FS 來指定欄位分隔符,效果如下:在这里插入图片描述

在上圖中,BEGIN 關鍵字部分的輸出內容沒有顯示出來,知道是爲什麼嗎?
因爲最後將輸出通過管道傳入了 tail -n 5 命令,該命令的效果是輸出最後 5 行數據,所以最開始輸出的內容也沒無法顯示了,這並不是指令碼 BUG 。

19.2 sed 編輯器基礎

介紹一些常用的 sed 命令。

19.2.1 更多的替換選項

通過一些選項,讓 s 命令 在替換文字時操作更靈活。

19.2.1.1 替換標記

預設情況下,在執行替換命令時,只會替換每行出現的第一個匹配項,如果每行有超過一個匹配項,那麼後續的都會被忽略,效果如下:在这里插入图片描述
在上圖中可以看到,目標文字中每行都有兩個 test ,sed 命令希望將 test 替換成 trail ,但命令執行後,每行都只有第一個 test 被替換了,後續的 test 沒有發生變化。
如果新增 替換標記 ,有一種方式可以解決上述情況。首先瞭解一下替換標記的四種可用方式:在这里插入图片描述
在上述方式中,第二種標記又被叫做全域性替換,效果如下:在这里插入图片描述
從上圖中可以看到,指定檔案中,所有的 test 都被替換成了 trail 。
第一種方式是通過數位標記,指定要替換的匹配項,效果如下:在这里插入图片描述
第三種方式是將被替換行的內容列印出來,效果如下:在这里插入图片描述
在上圖中可以看到,使用 sed 命令後的替換目標是 second 欄位,該欄位只有第二行數據存在一次匹配。當第一次使用該命令後,將所有被掃描的行都進行輸出。當第二次在替換命令某位替換 p 標記 後,在所有被掃描的行都輸出後,再次輸出了被替換內容的第二行,這就是 p 標記 的效果。
所以在使用該命令時一般會攜帶 sed -n 命令,-n 選項可以遮蔽 sed 命令預設的輸出內容,結合 p 標記 的效果,就可以只顯示被替換內容的行,如上圖第三次的效果。
第四種方式是將被替換內容的行輸出到指定檔案,效果如下:在这里插入图片描述
在上圖中可以看到,命令執行完成後,檢視 result.txt 的內容就是被替換內容的第二行。

19.2.1.2 替換字元

在 sed 命令中替換內容時,如果部分內容涉及到敏感字元,例如本身就要作爲替換操作分隔符的 正斜線( / ) ,那麼操作起來就非常麻煩,效果如下:在这里插入图片描述
這個時候其實可以指定其他字元來作爲替換操作的分隔符,例如 感嘆號( ! ) ,效果如下:在这里插入图片描述

19.2.2 使用地址

預設情況下,sed 命令會作用到指定數據的所有行。如果想讓命令作用於特定行或某些行,就需要用到 行定址( Line Addressing ) 。
在 sed 編輯器中有兩種行定址方式:

  • 通過數位形式指定行區間
  • 通過文字模式過濾指定行
19.2.2.1 數位形式的行定址

sed 編輯器會將目標文字的第一個編號爲 1 ,第二行編號爲 2 ,以此類推。在使用數位形式的行定址時,有以下三種方式可選:

  1. 2s ,表示單個隻影響第二行
  2. 2,3s ,表示影響第二到第三行
  3. 2,$s ,表示從第二行開始,一直到最後一行都受影響,美元符號( $ ) 表示最後一行
    第一種形式的效果如下:在这里插入图片描述
    在上圖中可以看到,只有第二行數據發生了變化。
    第二種形式的效果如下:在这里插入图片描述
    在上圖中可以看到,第二行和第三行的數據都發生了變化。
    第三種形式的效果如下:在这里插入图片描述
    在上圖中可以看到,從第二行開始一直到最後一行的數據都發生了變化。
19.2.2.2 使用文字模式過濾器

sed 編輯器允許對存在指定文字的行進行內容替換,效果如下:在这里插入图片描述
在上圖中可以看到,sed 命令首先在目標文字中找到 asing1elife 存在的行,然後將該行的 My 替換成 He ,而其他不存在 asing1elife 的行則不受影響。
該模式如果結合正則表達式,將會發揮更強大的威力。

19.2.2.3 命令組合

如果希望在單行執行多個命令,使用 花括號 在 多行模式 下將多個命令進行包裹即可,效果如下:在这里插入图片描述
在上圖中可以看到,sed 命令首先指定了受影響的行數是第二行,然後在第二行中進行了兩次替換。

19.2.3 刪除行

使用 d 命令 可以刪除 定址模式匹配到的指定行,d 命令 的定址模式和 s 命令 的規則一致。
該命令需要注意以下兩點:

  1. 隻影響流輸出,不會影響原檔案
  2. 必須加入定址模式,否則流輸出的所有數據都會被刪除
    指定單行的效果如下:在这里插入图片描述
    指定多行的效果如下:在这里插入图片描述
    指定開始行到最後一行的效果如下:在这里插入图片描述
    指定文字的效果如下:在这里插入图片描述
    還可以通過文字的方式來指定範圍,效果如下:在这里插入图片描述
    但該模式要慎用,因爲對於 sed 編輯器來說,第一個文字的匹配是打開了行刪除功能,第二個文字的匹配則是關閉了行刪除功能。所以如果一直沒有匹配到第二個文字,就會因爲無法關閉行刪除功能而導致將後續的內容全部刪除,效果如下:在这里插入图片描述
    又或者目標檔案的數據存在重複,就會導致 sed 編輯器再次匹配到第一個文字而開啓行刪除功能,效果如下:在这里插入图片描述

19.2.4 插入和附加文字

sed 編輯器的 i 命令 會在指定行之前增加一行新數據,a 命令 會在指定行之後增加一行新數據,效果如下:在这里插入图片描述
需要注意的是,插入和附加命令使用的是反斜線( \ ) ,而替換命令使用的是正斜線( / )。
如果要同時插入或追加多行文字,需要在使用多行模式時,在每行文字的末尾新增 反斜線( \ ) ,效果如下:在这里插入图片描述

19.2.5 修改行

sed 編輯器的 c 命令 會修改指定行的所有數據內容,效果如下:在这里插入图片描述
需要注意的是,修改命令使用的也是反斜線( \ ) 。

19.2.6 轉換命令

sed 編輯器的 y 命令 可以處理單個字元,格式是 sed [address]y/inchars/outchars/ ,該命令會將 inchars 中的每個字元與 outchars 中的每個字元進行一一對應後分別替換,效果如下:在这里插入图片描述
在上圖中可以看到,轉換命令預設就是全域性效果 ,並不像替換命令一樣需要使用 g 選項來開啓全域性替換效果。不過遺憾的是,轉換命令的轉換效果是否全域性,是不可選的,預設就是全域性,也只能是全域性轉換。
需要注意的是,inchars 和 outchars 的長度必須相同,否則會報錯,效果如下:在这里插入图片描述

19.2.7 回顧列印

除了替換命令中的 p 選項 可以用於列印被替換的行,還有以下三個命令可以列印數據流的資訊:
p 命令 用於列印文字行
= 命令 用於列印行號
l 命令 用於列出行,是小寫的 L

19.2.7.1 列印行

p 命令 可以列印指定的行內容,但建議和 sed -n 命令結合使用,效果如下:在这里插入图片描述
在上圖中可以看到,第一次使用 p 命令時,由於 sed 編輯器預設的輸出效果,首先輸出了完整的流數據,才輸出了 p 命令匹配的行內容。第二次結合 sed -n 命令遮蔽了預設輸出後,就可以只看到 p 命令的輸出結果了。
p 命令也支援行定址,效果如下:在这里插入图片描述

19.2.7.2 列印行號

sed 編輯器預設會爲目標文字的每一行新增編號,使用 = 命令 可以將這個編號輸出,效果如下:在这里插入图片描述

19.2.7.3 列出行

l 命令 的作用是列印出數據流中原本不可列印的 ASCII 字元,效果如下:在这里插入图片描述

19.2.8 使用 sed 處理檔案

19.2.8.1 寫入檔案

w 命令 可以將目標檔案的指定行寫入到指定檔案,效果如下:在这里插入图片描述

19.2.8.2 從檔案讀取數據

r 命令 允許將指定檔案的內容插入到目標檔案的指定位置,效果如下:在这里插入图片描述