1. 程式人生 > >sed在指定行上刪除和新增字元

sed在指定行上刪除和新增字元

引言

我在一個專案中需要釋出版本,兩個客戶的需求基本相同,只有是在一個fm34(消迴音)模組上一個有該功能,另外一個沒有。那麼就存在在發版本的時候根據需要開啟和關閉關於fm34相關的程式碼。

其中的一個就是是否需要inmod一個ko檔案,我的處理是:

  • 在指令碼中有inmod該ko的一行程式碼,但是預設是被註釋掉的
  • 在給需要該功能的客戶釋出版本時,通過sed將改行的註釋去掉(shell中的#字元)
  • 編譯出帶有fm34功能的版本
  • 釋出版本完成後,記得將該行在註釋回去(有可能在給另外一個客戶發版本)

在這裡,我就需要如何在指令碼中自動完成上面的操作,先給出最終的指令碼程式碼:

#!/bin/bash

# enable snd-soc-wmt-fm34
sed -i '/snd-soc-wmt-fm34/s/^#//' fs_patch/load_drivers.sh

source release_Common.sh

# disable snd-soc-wmt-fm34 back
sed -i '/snd-soc-wmt-fm34/s/^/#&/' fs_patch/load_drivers.sh

上面的程式碼主要是包括一下幾個步驟:

  1. 刪除行首的#字元,開啟註釋部分程式碼
  2. 編譯版本
  3. 將指定行程式碼再次註釋起來

sed行首刪除一個字元

sed -i '/snd-soc-wmt-fm34/s/^#//' fs_patch/load_drivers.sh

-i表示在原始檔案上進行修改。

       -i[SUFFIX], --in-place[=SUFFIX]
              edit files in place (makes backup if extension supplied)

s/^#//表示將字串開頭的#字元替換為空(即去除行首的#字元)

       s/regexp/replacement/
              Attempt  to  match  regexp  against  the  pattern  space.  If successful, replace that portion matched with replacement.  The replacement may contain the special character & to refer to that portion of  the  pattern space  which  matched,  and  the  special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.

其中s/regexp/replacement/命令支援address ranges,在該指令碼中使用的是正則表示式匹配確定address ranges的方式:

/snd-soc-wmt-fm34/表示匹配含有snd-soc-wmt-fm34字串的行

       /regexp/
              Match lines matching the regular expression regexp.

除了使用/regexp/的方式匹配特定行,sed還支援直接指定行號的方式進行操作,則上面的指令碼也可以使用採用下面的方式完成:

sed -i '49s/^#//' fs_patch/load_drivers.sh

       number Match only the specified line number.

注意,上面的數字前後都沒有任何的附加字元。

sed行首新增一個字元

sed -i '/snd-soc-wmt-fm34/s/^/#&/' fs_patch/load_drivers.sh

注意,這裡和上面的刪除操作唯一的不同就在於s/^/#&/部分。其中,^字元匹配行首,#字元是一般字元表示新增該字元,&字元是我們這裡需要重點關心的。在上面的關於s/regexp/replacement/命令描述時有以下欄位:

The replacement may contain the special character & to refer to that portion of  the  pattern space  which  matched,  and  the  special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.

這裡提到了兩種特殊字元:

&:refer to that portion of  the  pattern space  which  matched,即表示前面的正則表示式匹配出來的部分,而在這裡指的就是行首位置。實際上,在此處我們完全可以不要&字元,也是可以完成任務的。

\1...\9:refer to the corresponding matching sub-expressions in the regexp,主要用於多匹配時(如匹配行中的特定位置)分別表示前面的正則表示式匹配出來的部分,這裡的多匹配需要使用()來進行分割,如上面的程式碼可以分別使用下面兩種方式進行實現:

sed -i '/snd-soc-wmt-fm34/s/\(^\)/\1#/' fs_patch/load_drivers.sh
sed -i '/snd-soc-wmt-fm34/s/\(^\)\(.*\)/#\2/' fs_patch/load_drivers.sh

具體內容請參考正則表示式相關知識。

其它

本例中是根據工作需要在行首新增和刪除字元,如果是在行尾進行操作,則需要使用&萬用字元;而如果需要在行中的其它位置進行操作,則可能就需要使用到多匹配的方式。