Sed 全稱 Stream editor,一個流線式的非交互式的編輯器。它每次讀取一行放入模式空間緩衝區中,直到全部命令都執行完後把結果送往屏幕,而後讀取下一行。由於是將輸入內容複製到緩衝區處理,因此不會對原文件有任何影響,若是須要保存處理後的結果能夠重定向生成新的文件。linux
本文全部示例均基於txt.log文件,其中增長了行號。具體內容以下:bash
1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin 11 operator:x:11:0:operator:/root:/sbin/nologin 12 games:x:12:100:games:/usr/games:/sbin/nologin 13 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin 14 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 15 nobody:x:99:99:Nobody:/:/sbin/nologin 16 dbus:x:81:81:System message bus:/:/sbin/nologin 17 vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin 18 abrt:x:173:173::/etc/abrt:/sbin/nologin 19 haldaemon:x:68:68:HAL daemon:/:/sbin/nologin 20 ntp:x:38:38::/etc/ntp:/sbin/nologin 21 saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin 22 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 23 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 24 tcpdump:x:72:72::/:/sbin/nologin 25 nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
定址即指定sed 處理的範圍,默認是輸入內容的每一行。有兩種方式:行號和正則。具體見下表ssh
Sed 定址方式詳解tcp
選項 | 含義 | 備註 |
---|---|---|
x | 第x行 | sed -n '3p' /etc/passwd 輸出第3行 |
$ | 最後一行,固定寫法 | sed -n '$p' /etc/passwd |
x~Nth | 從第x行開始,返回每隔N行的 | sed -n '1~2p' /etc/passwd 輸出奇數行 |
x,y | x 到 y 之間的行(包含x和y) | sed -n '1,3p' /etc/passwd 輸出1到3行 |
/pattern/ | 查詢包含模式的行 | sed -n '/dae/p' /etc/passwd 打印含有dae的行 |
/pattern/,/pattern/ | 包含兩個模式間的 | sed -n '/root/, /mail/p' /etc/passwd |
/pattern/,x | 模式跟行號間的 | sed -n '/root/, 10p /etc/passwd |
x,/pattern/ | 行號跟模式間的 | sed -n '1,/da/p' /etc/passwd |
addr1, +N | 從開始位置起的後N行 | sed -n -e '1, +3p' -e /etc/passwd |
x,y! | 除了x,y 以外的全部行 | !表示在前邊條件知足後,直接取反 |
行號或者單個模式的容易理解,再也不贅述。下邊着重演示兩個模式及行號與模式混用的細節。歸納講,模式在前邊,則進行屢次匹配直到最後一行;若是在後邊,只發生一次匹配,若無匹配到有效行則默認處理到最後一行。先找出包含root 和 daemon的行,代碼以下: 編輯器
sed -n '/root/p' txt.log #找出包含root的行 ##====================== # 1 root:x:0:0:root:/root:/bin/bash # 11 operator:x:11:0:operator:/root:/sbin/nologin ##====================== sed -n '/daemon/p' txt.log #找出包含daemon的行 ##====================== # 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin # 19 haldaemon:x:68:68:HAL daemon:/:/sbin/nologin ##====================== sed -n '/mail/p' txt.log #找出包含mail的行 ##====================== # 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin ##======================
#找出包含root到daemon之間的行 sed -n '/root/,/daemon/p' txt.log ##========================== # 分析可知root有兩行(1,11),daemon有兩行(3,19) # 匹配到第一行後,找daemon 在第三行,因此先輸出1,3行 # 因爲起始的模式會屢次匹配,則發起第二次查找11行,因此返回11-19行 # 從20行後繼續找root,一直到最後一行,沒有了,退出 ##========================== #依據上述分析,查出/daemon/ 和 /mail/之間的行,結果是什麼呢 sed -n '/daemon/, /mail/p' txt.log ##========================== # 返回的結果是3-9行和19-25行 # daemon(3,19),,mail(19),txt.log 共25行 # sed -n '/mail/, /daemon/p' txt.log 返回哪些行呢,爲何? ##==========================
#起始爲模式時總會返回模式匹配的行 sed -n '/root/, 8p' txt.log #輸出1-8與11行 sed -n '/mail/, 8p' txt.log #輸出第9行
sed -n '2, /daemon/p' txt.log #輸出2-3行,以最早找到的daemon爲準 sed -n '10,/mail/p' txt.log #輸出10-25行,mail(9) 10行後未匹配,直到最後一行,
選項 | 釋義 | 示例 |
---|---|---|
-n | 配合p命令使用,只打印匹配的行 | sed -n '1,3p' txt.log 不加n是輸出因此行與匹配行 |
-e | 用於執行多個命令 | sed -n -e '/root/p' -e '/root/=' txt.log |
-i | 直接修改文件內容 | sed -i '/root/Root/s' txt.log |
-r | 支持擴展正則 |
#匹配行後新加一行 sed '/root/anewafter' txt.log sed '10,$/anewafter' txt.log #匹配行前新加一行 sed '/root/inewbefore' txt.log sed '10,$/inewbefore' txt.log
#刪除匹配的行,行內的刪除用替換實現 sed '/root/d' txt.log
替換命令有三個:s,c,y功能略有差別,另外在講緩衝區時,也會涉及另外一種替換實現。post
#c 表示將匹配的全部行的內容替換成新的字符串 sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config sed '1,10chello' txt.log #將1-10行的內容替換爲hello #y 一對一替換,字符數必須相等且不支持正則,不然報錯 sed '1,10y/r/R/' txt.log # 將1-10行的小寫r 換成大寫R #s 支持正則 ##======================= # 支持元字符正則 # 分組\(..\) s/\(love\)able/\1rs/ 最多到\9 # & 保存搜索字符 s/love/**&**/ 將love 替換成 **love** # \< /> 匹配單詞開始和結尾 # \{m,n\} 支持限定符 ##======================= sed '1,10s/^.*$/#&/' txt.log #1-10行開頭加上# sed 's/^/#/' txt.log ##======================= # 跟s配合的命令 # p 打印 sed 's/r/R/p' 能夠結合-n選項使用 # g 替換每行全部出現的 sed -n 's/r/R/gp' # N 替換每行第N個 sed -n 's/r/R/2p' # w 將結果寫入文件 sed 's/r/R/w output' txt.log ##======================= sed -n '1,10s/r/R/p' txt.log #把1-10行的r換成大寫,每行的第一個 sed -n 's/\([Rr]\)oot/\1OOT/gpw output.res' txt.log
#將結果寫入新文件 w sed '1,5w head5.log' txt.log #匹配的1-5行寫入head5.log且所有輸出到屏幕 #從文件裏讀取 r sed '/root/r head5.log' txt.log #在匹配行後加上從文件中讀取的內容 #退出命令q 表示完成指定地址匹配後當即退出 sed '/root/ q' txt.log #匹配到第一個root 後當即退出 #顯示控制字符 l sed -n 'l' txt.log #打印出含有控制字符的行 #輸出文件行號 = sed -n '/root/=' txt.log #打印出匹配的行號
包括多命令執行,緩衝區讀寫實現的移動和替換功能等。spa
##=============== # 多命令有三種方式 sed -e '' -e '' 上邊說過 # 大括號{命令1;命令2} 如 sed -n '/root/{p;=}' # 分號間隔多個命令 '命令1;命令2' 如 sed 's/r/R/;s/b/B/' ##=============== sed -e 's/R/r/' -e 's/o/O/g' txt.log sed 's/R/r/;s/o/O/g' txt.log sed -n '/root/{s/R/r/;s/o/O/}' txt.log #處理匹配行的下一行 n sed -n '/root/{n;s/r/R/g;}' sed '/root/{n;y/b/B/;}' txt.log #{}中最後一條命令的分號不能省 ##=============== # 模式緩衝區和保持緩衝區 # 命令h和H 將模式緩衝區的內容放到保持緩衝區 h 是覆蓋 H是追加 # 命令g和G 將保持緩衝區的內容放到模式緩衝區 g 是覆蓋 G是追加 # x 互換模式緩衝區和保持緩衝區的內容 # 通常用於移動文本內部的行或是用某行替換某行 ##=============== sed '/root/h;/daemon/G' txt.log #將離daemon前邊的最後的一個root 行追加到 daemon後邊 sed '/root/h;/daemon/x;' txt.log #將daemon行替換爲前邊最後的一條root 行
爲了強化記憶,基於txt.log 的內容提出了幾個題目,分A,B,C 三級,歡迎在評論區亮出你的答案,想看標準答案別忘了打賞,看到後私信給你 :) ,再偷偷的告訴你一句,只要仔細看完教程,答案不在話下!3d
sed 強化練習code
A級 |
---|
1. 打印出偶數行 sed -n '2~2p' txt.log 或 sed '1~2d' txt.log |
2. 打印出不包含數字3或5的行 sed -n '/[35]/!p' txt.log |
3. 在含有大寫字母行的下邊插入一空行,並將結果保存成blank_line.log sed '/[A-Z]/a\\n' txt.log > blank_line.log |
4. 刪除blank_line.log全部的空行並保存 sed -i '/^$/d' blank_line.log |
B級 |
1. 刪除每行第一個字母前的全部字符並保存爲 nonu.log sed -n 's/\([^A-Za-z]\{1,\}\)//pw none_num.log' txt.log |
2. 將包含root的首行開頭加上#,其它行不做處理 sed '/root/{s/^/#/;q;}' txt.log |
3. 將全部的非零的一位數字前補零 sed -n 's/\<\([1-9]\{1\}\)\>/0\1/gp' txt.log |
C級 |
1. 刪除含有root行下的連續3行 sed '/root/, +3d' txt.log |
2. 互換包含root 和 daemon的行 |