![]() |
![]() |
![]() |
![]() |
![]() |
$ | sed | -e | '1,8 | s/ | [Tt]he/ | THE/ | g' | MyFile.txt |
↑ | ↑ | ↑ | ↑ | ↑ | ↑ | ↑ | ||
選 項 |
位 址 |
命 令 |
樣 板 |
取 代 |
旗 幟 |
檔 案 |
$ echo 'This is a book' | sed 's/is/IS/g' ←將字串〝is〞改為〝IS〞(單字前沒加空隔) ThIS IS a book $ echo 'This is a book' | sed 's/ is/ IS/g' ←樣板和取代前加一空隔 This IS a book $ echo 'This is a book' | sed 's/\<is\>/IS/g' ←用正規表示法的單字配匹 This IS a book $ sed 's/\<is\>/IS/g' fileA ←檔案〝fileA〞把〝is〞改為〝IS〞 $ sed 's/\<is\>/IS/g' fileA fileB fileC ←也可一次輸入好幾個檔案 |
$ echo 'this is a apple' | sed 's/a/AN/' ←將〝a〞改為〝AN〞(只取代搜尋到的第一個樣板就停止) this is AN apple $ echo 'this is a apple' | sed 's/a/AN/g' ←多加 FLAG〝g〞故輸的〝apple〞也變〝ANpple〞 this is AN ANpple $ echo 'this is a apple' | sed 's/ is//g' ←將單字〝is〞刪掉(刪掉用空字串來取代)記得〝is〞前要加一空格寫成〝 is〞,不然〝this〞串中的〝is〞也會被刪除) this a apple $ cat my_file.txt | sed '4,5 s/Google/Yahoo/g' > new.txt ←將檔案〝my_file.txt〞中第 4~5 行中的字串〝Google〞改〝Yahoo〞並存檔為〝new.txt〞 $ sed '4,5 s/Google/Yahoo/g' < my_file.txt > new.txt ←功能同上 |
$ echo 'this is a apple' | sed 's/a/an/' | sed 's/apple/APPLE/' ←將〝a〞改為〝an〞&〝apple〞改為大寫 this is an APPLE $ echo 'this is a apple' | sed -e 's/a/an/' -e 's/apple/APPLE/' ←功能同上 |
$ echo 'this is a apple' | sed 's:a:AN:' ←將〝a〞改為〝AN〞(用〝:〞當 delimiter) this is AN apple $ echo '/home/frank/' | sed 's#/#\\#g' ←將〝/〞改為〝\〞(用〝#〞當 delimiter) \home\frank\ |
$ sed '1,5 s/ [aA]/ one/' file ←將 1~5 行〝a〞或〝A〞改〝one〞 $ sed '5 s/ [aA]/ one/' file ←只將第 5 行〝a〞或〝A〞改〝one〞 $ sed 's/ [aA]/ one/' file ←省略位址,整個檔案〝a〞或〝A〞改〝one〞 |
$ sed '3,$ s/^can/CAN/' file ←將 3 行到最後一行開頭為〝can〞改大寫 |
$ sed '/The/,/Whe/ s/ can/ CAN/g' < re.txt ←位址範圍從有〝The〞到〝When〞之間的行,字串〝can〞改〝CAN〞 $ sed '/[Cc]an$/ s/a/A/g' re.txt ←將符合〝[Cc]an$〞pattern 的那行〞a〞改〝A〞 |
$ sed '2,/The/ s/[0-9]/#/g' re.txt ←第二行開始到符合〝The〞那行之間任何數字改為字串〝#〞 $ sed '/google/, $ s/a/A/g' re.txt ←從從有〝google〞那行到最後一行〝a〞改大寫 |
語法: sed [-OPTION] [ADD1][,ADD2] [COMMAND] [/PATTERN][/REPLACEMENT]/[FLAG] [FILE]] | 註 | ||
指令名稱/功能/命令使用者 | 選項 | 功能 | |
sed/ (stream editor)檔案字串修改/ Any |
-e | 執行 sed 的 script 語法 | 如沒使用〝-f〞選項此為預設選項 |
-f | 選用外部的 script 檔來執行 | ||
-n | 不輸出 pattern space 到螢幕 | ||
-l # | 時常和 COMMAND l(小寫的〝L〞)一起使用時,指定每一行的長度 | # 為數字 | |
-r | 使用延伸正規表示 | ||
--help | 指令自帶說明 |
$ echo 'this is a pen' | sed -e 's/t/T/' -e 's/pen/&cil/' ←將〝t〞改為〝T〞and〝pen〞改為〝pencil〞 This is a pencil $ sed -e 's/a/A/' -e '/this/ q' -e 'l' MyFile ←許多 sed COMMAND 要使用,就一定要用〝-e〞選項 (此範例為把檔案〝MyFile〞內的文字〝a〞改〝A〞 直到某一行有字串〝this〞就結束 & 列出不顯示的字元) |
$ cat sed_scr ←例如有一外部 script 檔〝sed_scr〞功能為把 a~d 改大寫 s/a/A/g s/b/B/g s/c/C/g s/d/D/g $ echo 'abcdefg' | sed -f sed_scr ABCDefg |
$ sed -f sed_scr < MyFile > TargetFile ←用外部 script 檔〝sed_scr〞處理檔案〝MyFile〞處理後存成〝TargetFile〞 |
$ ls -d /etc/* | sed -n '/[A-Z][0-9]/ p' ←選項〝-n〞配合 FLAG〝p〞只列出符合樣板的行(類似指令〝grep〞) /etc/X11 $ echo -e 'Line1\nLine2\nLine3' | sed -n 's/Line2/Line two/p' ←只列出有改變的行 Line two |
$ echo -e 'This\tIs\tA\tDog' | sed -nl 10 'l' ←指定換行的長度=10 This\tIs\ \tA\tDog$ |
$ echo 'Why an apple $9.99?' | sed 's/99?/88/g' ←將字串〝99?〞改為〝88〞 Why an apple $9.88 上例中樣板〝99?〞如加選項〝-r〞強迫用延伸正規表示法來解讀是匹配字串〝9〞或〝99〞,結果可能很不一樣(下例)。 $ echo 'Why an apple $9.99?' | sed -r 's/99?/88/g' ←加選項〝-r〞用延伸正規表示法 Why an apple $88.88? |
Sed Flags | |
[g][ 數字] | 全部取代或指定取代第幾個 |
I | 忽略 pattern 大小寫 |
p | 列印 |
w | 寫入檔案 |
$ echo 'this is an issue' | sed 's/is/IS/' ←〝is〞→〝IS〞,但預設只取代搜尋/取代到第一個 pattern thIS is an issue $ echo 'this is an issue' | sed 's/is/IS/g' ←加 flag〝g〞全部取代 thIS IS an ISsue |
$ echo 'aaaaa aaaaa' | sed 's/a/A/3' ←第 3 個符合的樣本才取代 aaAaa aaaaa |
$ echo 'aaaaa aaaaa' | sed 's/a/A/3g' ←第 3 個符合的樣本才開始取代 aaAAA AAAAA |
$ echo 'this is an apple' | sed 's/APPLE/banana/I' this is an banana |
$ echo 'this is a pen' | sed 's/pen/pencil/p' this is a pencil ←此行輸出是 pattern space 的內容 this is a pencil ←此行輸出是 current pattern space 的內容 $ echo -e 'Line1\nLine2\nLine3' | sed -n '/[13]/p' ←和選項〝-n〞配合只列出符合的樣板 Line 1 Line 3 |
$ man cp | sed 's/copy/{&}/w cp.txt' ←將 man page 中的〝copy〞字串加上大括號〝{}〞寫入檔案〝cp.txt〞 |
$ man cp | sed -n 's/COPY/{&}/Igpw cp.txt' ←FLAG 不只一個時,如有和檔案有關 FLAG(如〝w〞) 一定要加在最後 |
$ cat sed_scr1 # conver a..d to A..D ←此行為註解,不會被執行 s/a/A/g !s/b/B/g #←以〝!〞開頭的行不會被執行 #s/c/C/g #←〝#〞開頭的行被當註解,不會被執行 s/d/D/g $ echo 'abcdefg' | sed -f sed_scr1 AbcDefg |
$ sed -n '10,15 !p' MyFile ←不輸出檔案 10~15 行 $ cat MyFile | sed -n '/Apple/ !=' ←列出字串沒有〝Apple〞的行數 |
$ cat sed_scr2 # grouping with {} { #←套餐開始 s/a/A/g !s/b/B/g #s/c/C/g s/d/D/g } #←套餐結束 $ echo 'abcdefg' | sed -f sed_scr2 AbcDefg |
$ cat sed_scr3 # grouping with {} 1,3 { s/a/A/g !s/b/B/g #s/c/C/g s/d/D/g } $ head 3 /etc/passwd | sed -f sed_scr3 root:x:0:0:root:/root:/bin/bAsh bin:x:1:1:bin:/bin:/sbin/nologin DAemon:x:2:2:DAemon:/sbin:/sbin/nologin |
$ cat sed_scr4 /hello/ { #←有誤!因套餐開始的〝{〞要和位址範圍寫在同一行 s/a/A/ } |
$ cat sed_scr5 # grouping with nest burly braces 10,$ { /chapter 1/,/chapter 2/ { s/a/A/g s/b/B/g } } |
$ cat sed_scr6 # if pattern 'google' found,char "a"->"A" else "b"->"B" /google/ b capitalA #←樣板條件跳躍,如符合'google'則跳躍到 label 'capitalA' { s/b/B/g b end #←無條件跳躍到 label 'end' } :capitalA #←label 'capitalA' { s/a/A/g } :end #←label 'end' $ echo -e 'google abc\nyahoo abc' | sed -f sed_scr6 google Abc yahoo aBc |
$ cat sed_scr7 s/g..g../GOOGLE/g t capitalA #←如樣板取代成功則跳到標籤 'capitalA',否則則執行下一行 b end :capitalA s/a/A/g :end $ echo -e 'google abc\nyahoo abc' | sed -f sed_scr7 GOOGLE Abc yahoo abc |
$ cat sed_scr8 s/g..g../GOOGLE/g T end #←如樣板取代不成功則跳到標籤 'end' s/a/A/g :end $ echo -e 'google abc\nyahoo abc' | sed -f sed_scr8 GOOGLE Abc yahoo abc |
sed 指令 | 位址 | 功能 | 註 |
:label | 標籤 | 參考流程控制 | |
# | 註解 | 參考流程控制 | |
! | 禁能 | 參考流程控制 | |
{} | 命令套餐 | 參考流程控制 | |
b label | 無條件跳躍或樣板條件跳躍到 label | 參考流程控制 | |
t label | 樣板取代成功跳躍 | 參考流程控制 | |
T label | 樣板取代不成功跳躍 | 參考流程控制 | |
= | 範圍 | 列印行號 | |
a , i 或 a\, i\ | 範圍 | 插入文字 | |
c 或 c\ | 範圍 | 取代行 | |
d | 範圍 | 刪除 pattern space 或指定的行 | |
D | 範圍 | 刪除 pattern spac內的第一個字元一直到換行 | |
g | 範圍 | hold space 複製到 pattern space | |
G | 範圍 | hold space 添加到 pattern space | |
h | 範圍 | pattern space 複製到 hold space | |
H | 範圍 | pattern space 添加到 hold space | |
l | 範圍 | (小寫的 L)強制列印不顯示的字元 | |
n | 範圍 | 讀取下一行 | |
N | 範圍 | 添加下一行到 pattern space | |
p | 範圍 | 列印 current pattern space | |
P | 範圍 | 列印 current pattern space內的第一個字元一直到換行 | |
q | 單一位址 | 立即離開 sed | |
Q | 單一位址 | 立即離開 sed 但不輸出 current pattern space | |
r | 單一位址 | 把檔案的內容插入文字 | |
s | 範圍 | 搜尋/取代 | |
w | 範圍 | 將 current pattern space 寫到檔案 | |
x | 範圍 | pattern space 和 hold space 資料互換 | |
y | 範圍 | 轉換字元 |
$ sed -n '/home/=' /etc/passwd ←列出檔案〝/etc/passwd〞有字串〝home〞 的行數 37 38 39 |
$ man sed | sed -n '$=' ←列出 sed 的 man page 共有幾行 261 |
$ echo -e 'Line1\nLine2\nLine3' | sed '/Line2/ aINSERT' ←樣板〝Line2〞的下一行插入〝INSERT〞 Line1 Line2 INSERT ←插入的行 Line3 $ sed '6,$ aHello' MyFile ←檔案〝MyFile〞6 到最後一行各插入〝Hello〞 |
$ echo -e 'Apple\nBanana\nCoconut' | sed '3 iOrange\nDurian' ←第三行之上插入二行 Apple Banana Orange ←插入的行 Durian ←插入的行 Cocount |
$ cat sed_scr9 /pattern/ a\ Insert line1 \ Insert Line2 |
$ echo -e 'Line1\nLine2\nLine3' | sed '/2$/ cREPLACE LINE' ←以〝REPLACE LINE〞取代最後一字元為〝2〞的行 Line1 REPLACE LINE Line3 $ echo -e '1\n2\n3\n4\n5' | sed '1,3 cREPLACE 1-3' ←以一行取代多行 REPLACE 1-3 4 5 |
$ sed '4,8 d/' MyFile ←刪除 4~8 行 $ sed '4,8 !d/' MyFile ←保留 4~8 行其餘皆刪除 $ sed '/pattern/ d' MyFile ←刪除匹配到 pattern 的行 $ sed '/pattern1/,/pattern2/ d' MyFile ←刪除匹配到 pattern1 到 pattern2 中間所有的行 $ sed '/^$/ d' ←刪除空白的行 |
$ sed -n '5,12 p' file ←列印〝file〞 5~12 行 $ sed -n '/regex1/,/regex2/ p' file ←列印〝file〞符合正規表示法 regex1 到 regex2 間的行 |
L | i | n | e | A | \n | L | i | n | e | B |
$ echo -e 'LineA\nLineB' | sed -e 'N' -e 's/\n/+/' ←用〝N〞讀下一行,再把換行字元〝\n〞改其他字串 LineA+LineB |
L | i | n | e | A | \n | L | i | n | e | B | \n | L | i | n | e | C |
L | i | n | e | B | \n | L | i | n | e | C |
$ echo -e 'LineA\nLineB\nLineC' | sed -e 'N' -e 'N' -e 'D' ←用二次〝N〞連讀二個下一行,再〝D〞刪除第一行 LineB LineC |
$ echo -e 'LineA\nLineB\nLineC' | sed -e 'N' -e 'N' -ne 'P' LineA |
$ cat sed_scr10 /ID/{ N #if matching "ID" append the next line /NAME/ { N #if 2nd line matching "NAME" append next line again /ADDRESS/ { D #delete 1st matched line } } } $ echo -e 'ID:123\nNAME:abc\nADDRESS:taipei' | sed -f sed_scr10 NAME:abc ←ID 那行被刪了 ADDRESS:taipei $ echo -e 'ID:123\nSEX:m\nADDRESS:taipei' | sed -f sed_scr10 ID:123 ←如樣板〝ID〞/〝NAME〞/〝ADDRESS〞 不是依序且是相鄰的行就不會被刪 SEX:m ADDRESS:taipei |
L | i | n | e | A |
L | i | n | e | B |
L | i | n | e | A | \n | L | i | n | e | B |
$ cat sed_scr11 /ID/{ h # if matching "ID" pattern-space copy to hold-space n # read next line /NAME/ { G # append hold-space to pattern-space } } p # print the current-pattern-space $ echo -e 'ID:123\nNAME:abc' | sed -nf sed_scr11 NAME:abc ID:123 |
$ echo -e 'as can\aner can can a can ' as canner can can a can ←輸出看不出異常 $ echo -e 'as can\aner can can a can ' | sed -n '/can$ /p' ←因最後的〝can〞多打了一空白,故用正規表示法的〝can$〞會匹配不到 $ echo -e 'as can\aner can can a can ' | sed -n '/canner /p' ←因有不會顯示的〝\a〞,故也匹配不到 $ echo -e 'as can\aner can can a can ' | sed -n 'l' ←用 COMMAND〝l〞(小寫的 L)讓不顯示的字元現形 $ as can\aner can can a can $ |
$ ls -l / | sed '/dev/ q' total 142 drwxr-xr-x 2 root root 4096 2012-07-04 19:48 bin drwxr-xr-x 4 root root 1024 2012-06-09 01:30 boot drwxr-xr-x 13 root root 4060 2013-10-31 19:50 dev $ ls -l / | sed '/dev/ Q' total 142 drwxr-xr-x 2 root root 4096 2012-07-04 19:48 bin drwxr-xr-x 4 root root 1024 2012-06-09 01:30 boot |
$ sed '10 q' MyFile ←列出檔案前 10 行,此時行為等於指令〝head -n〞 $ sed -e 's/a/A/' -e '/Hello/ q' MyFile ←搜尋和取代,但遇到〝Hello〞就結束 |
$ echo -e 'LineA\nLineB' | sed -e 'n' -ne 'p' LineB |
$ sed '3 r INSERT.txt' MyFile ←檔案〝MyFile〞第三行插入另一檔案〝INSERT.txt〞的內容 $ cat MyFile | sed '/ch1/,/ch2/ r INSERT.txt' ←樣板〝ch1〞和〝ch2〞之間插入另一檔的內容 $ sed '/ch1/ r INSERT.txt' MyFile ←符合樣板〝ch1〞那行之下插入另一檔案的內容 |
$ cat fileA | sed 's/i/I/g' > fileB ←如處理的檔案和要儲存的檔案不同,建議用重定向 $ cat fileA | sed 's/i/I/g w fileA' ←COMMAND〝w〞主要同在正在處理的檔案和要寫入的檔案是同一個 |
$ echo abcdefg | sed 'y/abc/ABC/' ABCdefg $ echo 'john smith' | sed 'y/nh/#&/' jo&# smit& $ echo '(2+3)*4' | sed 'y/()*/[]X/' [2+3]X4 |