本篇 ShengYu 將介紹如何使用 Linux 下的 sed 指令來取代/替換字串,相同地 sed 指令也可以在 macOS 下做字串取代,但有些情形需要一些改動詳見下面內容,平時在寫 Shell Script 時經常會使用到 sed 取代字串,由於 sed 這強大指令博大精深,又很容易忘記,所以在這邊會記錄一下我常用到的功能。
以下的 Linux sed 用法與範例將分為這幾部分,
- Linux sed 基本用法
- Linux sed 常用範例
- find 指令找到檔案後 pipe 給 sed 取代文字
- grep 指令搜尋內容符合的檔案 pipe 給 sed 取代文字
- shell script 中 find 找檔案後傳給 sed 指令
- shell script 中傳變數給 sed 指令
- sed 刪除符合特定字樣的那些行
- sed 轉換 hex string 成 byte string
那我們開始吧!
Linux sed 基本用法
這邊介紹 Linux sed 基本用法,假設我們要將設定檔裡某變數 :
冒號之後的任意字串取代掉,
今天有份 settings.conf 設定檔如下,1
2name: Alan
age: 18
情況1. 希望將裡面的在 settings.conf 裡取代所有的 Alan
字串, 替換成 Barry
,sed 指令如下,g
表示全部取代,沒有 g
的話只會取代一次,1
$ sed -i 's/Alan/Barry/g' settings.conf
情況2. 將 name:
後面的任何字元取代成 name: Duke
1
$ sed -i 's/name:.*/name: Duke/g' settings.conf
同樣的指令在 macOS 下要修改一下,在 -i
後面多加一個內容為空 ""
的參數,
否則會出現 unterminated substitute pattern。1
$ sed -i "" 's/name:.*/name: Duke/g' settings.conf
但是如果沒有使用 -i
的參數的話 Linux 與 macOS 使用的指令則相同,例如 sed 's/name:.*/name: Duke/g' settings.conf
,但是使用 -i
才會將結果寫回原本的檔案。
Linux sed 常用範例
以下為 Linux sed 常用範例,搜尋的字串如果內含空白的話,則空白前要加反斜線 \
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# 單檔取代, oldtext取代成newtext
$ sed -i 's/oldtext/newtext/g' <filename>
# 對當前目錄下所有的txt副檔名, oldtext取代成newtext
$ sed -i 's/oldtext/newtext/g' *.txt
# 取代有含空白的字串,abc d取代成a bcd
$ sed -i 's/abc\ d/a\ bcd/g' <filename>
# 取代 `http` 開頭的
# http://xxx.com/index.html -> https://xxx.com/index.html
$ sed -i 's/^http/https/g' <filename> # 將所有在行首的http字串替換成https,如果http不是在行首的字串,則不會被取代掉
# 取代 com. 結尾的
# https://xxx.com/index.html -> https://xxx.edu
$ sed -i 's/com.*/edu/g' <filename> # 將所有 "com.後面接任意字元任意長度" 的字串替換成 edu
# 刪除行首空格
$ sed 's/^[ \t]*//g'
# 刪除行末空格
$ sed 's/[ \t]*$//g'
find 指令找到檔案後 pipe 給 sed 取代文字
find 指令找到檔案後 pipe 給 sed 取代文字的方式如下,範例內容是假設我要找的檔案類型是 txt 副檔名,用 find 把所有 txt 副檔名找出來後將這些檔案名稱 pipe 給 sed 取代文字,將這些檔案裡的 http 全部取代成 https,1
2
3
4# Linux
find ./ -iname "*.txt" -type f | xargs sed -i 's/http/https/g'
# macOS
find ./ -iname "*.txt" -type f | xargs sed -i "" 's/http/https/g'
grep 指令搜尋內容符合的檔案 pipe 給 sed 取代文字
grep 指令搜尋內容符合的檔案 pipe 給 sed 取代文字的方式如下,範例內容是假設我要搜尋檔案內容有 http 的字串找出來後將這些檔案名稱 pipe 給 sed 取代文字,將這些檔案裡的 http 全部取代成 https,1
2
3
4# Linux
grep -ri "http" * -l | xargs sed -i 's/http/https/g'
# macOS
grep -ri "http" * -l | xargs sed -i "" 's/http/https/g'
如果 grep 換成 ag 的話,1
2
3
4# Linux
ag "http" -l | xargs sed -i 's/http/https/g'
# macOS
ag "http" -l | xargs sed -i "" 's/http/https/g'
shell script 中 find 找檔案後傳給 sed 指令
假如寫成 shell script 時,想要將變數帶進 sed 的參數裡的話,會發現剛剛上述的例子的 's/$1/$2/g'
單引號(single quotes)方式會失效,無法將 shell script 變數取值出來,這是因為要用雙引號(double quotes)的方式才能將 shell script 變數取值,所以就要改成 "s/$1/$2/g"
這樣的方式,如下範例中的 replace_http 函式,1
2
3
4
5function replace_http() {
find ./ -iname "*.txt" -type f | xargs sed -i "s/$1/$2/g"
}
replace_http "http" "https"
shell script 中傳變數給 sed 指令
在 shell script 要傳變數給 sed 處理的話,可以這樣寫,
以下範例是用 sed 將 abcabc 字串裡的 a 換成 z,1
2STR=abcabc
echo $STR | sed 's/a/z/g'
結果為1
zbczbc
sed 刪除符合特定字樣的那些行
以下範例是刪除 settings.conf 中符合 text 字樣的那些行,所以 settings.conf 裡有 3 行都符合的話就會刪除那 3 行,1
sed -i '/text/d' settings.conf
在 shell script 中寫成變數的話 sed 就要改用雙引號才能取得變數的字串數值,1
2PATTERN="text"
sed -i "/$PATTERN/d" settings.conf
PATTERN 中出現特殊字元的話,我自己的經驗是 sed 在遇到左中括號 [
會需要跳脫字元否則有機率會出錯,解決方式為在 PATTERN 裡的所有左中括號 [
前插入跳脫字元,1
2
3PATTERN="[2020-12-11]"
PATTERN2=`echo "$PATTERN" | sed 's/\[/\\\[/g'`
sed -i "/$PATTERN2/d" settings.conf
在 stackexchange 這篇有一些討論左中括號 [
會需要跳脫字元的討論。
sed 轉換 hex string 成 byte string
如果想要將 00123a4b
的 hex 字串 \x00\x12\x3a\x4b
轉成 byte 字串的話,可以透過 sed 來達成,sed 指令如下,1
2$ echo "00123a4b" | sed 's/../\\x&/g'
\x00\x12\x3a\x4b
如果是要將 00123a4b
的 hex 字串 0x00, 0x12, 0x3a, 0x4b,
轉成逗號間隔的話,就這樣使用,1
2$ echo "00123a4b" | sed 's/../0x&, /g'
0x00, 0x12, 0x3a, 0x4b,
參考
sed @ 工作筆記 :: 隨意窩 Xuite日誌
http://blog.xuite.net/yctseng/notes/24568350-sed
bash - How do I use variables in a sed command? - Ask Ubuntu
https://askubuntu.com/questions/76808/how-do-i-use-variables-in-a-sed-command
其它相關文章推薦
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux find 尋找檔案/尋找資料夾用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux grep 搜尋字串用法與範例
Linux ag 搜尋字串用法與範例(比 grep 還快)
Linux tee 同時螢幕標準輸出和輸出到檔案用法與範例
Linux xargs 參數列表轉換用法與範例
Linux tail 持續監看檔案輸出用法與範例
Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例
Linux wget 下載檔案用法與範例