1. 程式人生 > >Linux中sed文字處理工具原理及使用

Linux中sed文字處理工具原理及使用

Sed是什麼?

Sed是一種非互動式的流編輯器,可動態編輯檔案;流編輯器則會在編輯器處理資料之前基於預先提供的一組 規則來編輯資料流

Sed本身是一個管道命令,可以分析 standard input 的,主要是用來分析關鍵字的使用、統計等,此外還可 以將資料進行替換、刪除、選中、選取特定行等功能

Sed主要用來自動編輯一個或多個檔案,可以將資料行進行替換、刪除、新增、選取等特定工作,簡化對檔案 的反覆操作,編寫轉換程式等

sed引數 作用
-e 直接在命令列模式上進行sed動作編輯,此為預設選項;
-f 將sed的動作寫在一個檔案內,用–f filename 執行filename內的sed動作;
-i 直接修改檔案內容;
-n 只打印模式匹配的行;
-r 支援擴充套件表示式;
-h或–help 顯示幫助;
-V或–version 顯示版本資訊

常用命令:

元字元 功能
a\ 在當前行下面插入文字;
i\ 在當前行上面插入文字;
c\ 把選定的行改為新的文字;
d 刪除,刪除選擇的行;
D 刪除模板塊的第一行;
s 替換指定字元;
h 拷貝模板塊的內容到記憶體中的緩衝區;
H 追加模板塊的內容到記憶體中的緩衝區;
g 獲得記憶體緩衝區的內容,並替代當前模板塊中的文字;
G 獲得記憶體緩衝區的內容,並追加到當前模板塊文字的後面;
l 列表不能列印字元的清單;
n 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令;
N 追加下一個輸入行到模板塊後面並在二者間嵌入一個新行,改變當前行號碼;
p 列印模板塊的行。 P(大寫) 列印模板塊的第一行;
q 退出Sed;
b lable 分支到指令碼中帶有標記的地方,如果分支不存在則分支到指令碼的末尾;
r file 從file中讀行;
t label if分支,從後一行開始,條件一旦滿足或者T,t命令,將導致分支到帶有標號的命令處,或者到指令碼 的末尾;
T label 錯誤分支,從後一行開始,一旦發生錯誤或者T,t命令,將導致分支到帶有標號的命令處,或者到指令碼的末尾;
w file 寫並追加模板塊到file末尾;
W file 寫並追加模板塊的第一行到file末尾;
! 表示後面的命令對所有沒有被選定的行發生作用;
= 列印當前行號;
# 把註釋擴充套件到下一個換行符以前;
/g 表示行內全面替換;
/p 表示列印行;
/w 表示把行寫入一個檔案;
/x 表示互換模板塊中的文字和緩衝區中的文字;
/y 表示把一個字元翻譯為另外的字元(但是不用於正則表示式);
\1 子串匹配標記;
& 已匹配字串標記;
元字元 功能
^ 行首定位符
$ 行尾定位符
. 匹配除換行符以外的單個字元
* 匹配零個或多個前導字元
? 匹配零個或1個前導字元
+ 匹配1個或多個前導字元
| 或操作
\s 匹配單個空白字元(如\t)
\S 匹配單個非空白字元
\w 匹配單個單詞
\W 匹配單個非單詞
[] 匹配指定字元組內的任一字元
[^] 匹配不在指定字元組內的任一字元
[-] 匹配字符集的字元範圍
(..) 儲存已匹配的字元(括號前面要加反斜槓\,csdn沒顯示出來)
& 儲存查詢串以便在替換串中引用
< 詞首定位符
> 詞尾定位符
x{m} 連續m個x
x{m,} 至少連續m個x
x{m,n} 至少連續m個,但不超過n個x
(str) 正則表示式中對字串的引用(括號前面要加反斜槓\,csdn沒顯示出來)
中括號表示式 如[:alnum:],[:alpha:],[:digit:],[:lower:],[:upper:],[:punct:],[:space:]

#替換操作:s
sed ‘s/book/books/’ file
sed -n ‘s/test/TEST/p’ file #-n選項和p命令一起使用表示只打印那些發生替換的行
sed -i ‘s/book/books/g’ file #編輯檔案選項-i,會匹配file檔案中每一行的第一個book替換為books

#全域性替換:g
sed ‘s/book/books/g’ file #/g 標記會替換每一行中的所有匹配
echo sksksksksksk | sed ‘s/sk/SK/2g’ #需要從第N處匹配開始替換時,可以使用 /Ng
echo sksksksksksk | sed ‘s/sk/SK/3g’
echo sksksksksksk | sed ‘s/sk/SK/4g’

#定界符
#以上命令中字元 / 在sed中作為定界符使用,也可以使用任意的定界符
sed ‘s:test:TEXT:g’

sed ‘s|test|TEXT|g’
#定界符出現在樣式內部時,需要進行轉義:
sed ‘s//bin//usr/local/bin/g’

#刪除:d
sed ‘/^$/d’ file #刪除空白行
sed ‘2d’ file
sed ‘2,$d’ file
sed ‘$d’ file
sed '/^test/'d file

#已匹配字串標記&
#正則表示式 \w+ 匹配每一個單詞,使用 [&] 替換它,& 對應於之前所匹配到的單詞
echo “this is a test line” | sed ‘s/\w+/[&]/g’
#所有以192.168.0.1開頭的行都會被替換成它自已加localhost:
sed ‘s/^192.168.0.1/&localhost/’ file

#子串匹配標記\1
echo this is digit 7 in a number | sed ‘s/digit ([0-9])/\1/’
#命令中 digit 7,被替換成了 7。樣式匹配到的子串是 7,(…) 用於匹配子串,對於匹配到的第一個子串就 標記為 \1,依此類推匹配到的第二個結果就是 \2
echo aaa BBB | sed ‘s/([a-z]+) ([A-Z]+)/\2 \1/’
#love被標記為1,所有loveable會被替換成lovers,並打印出來
sed -n ‘s/(love)able/\1rs/p’ file

#組合多個表示式
sed ‘表示式’ | sed ‘表示式’
sed ‘表示式; 表示式’

#引用
#sed表示式可以使用單引號來引用,但是如果表示式內部包含變數字串,就需要使用雙引號
test=hello
echo hello WORLD | sed “s/$test/HELLO”

#選定行的範圍:,(逗號)
#所有在模板test和check所確定的範圍內的行都被列印
sed -n ‘/test/,/check/p’ file
#列印從第5行開始到第一個包含以test開始的行之間的所有行:
sed -n ‘5,/^test/p’ file
#對於模板test和west之間的行,每行的末尾用字串aaa bbb替換
sed ‘/test/,/west/s/$/aaa bbb/’ file

#多點編輯,e
#-e選項允許在同一行裡執行多條命令
sed -e ‘1,5d’ -e ‘s/test/check/’ file
#上面sed表示式的第一條命令刪除1至5行,第二條命令用check替換test。命令的執行順序對結果有影響。如果兩 個命令都是替換命令,那麼第一個替換命令將影響第二個替換命令的結果

#從檔案讀入:r
#file裡的內容被讀進來,顯示在與test匹配的行後面,如果匹配多行,則file的內容將顯示在所有匹配行的下面
sed ‘/test/r file’ filename

#寫入檔案:w
#在example中所有包含test的行都被寫入file裡
sed -n ‘/test/w file’ example

#追加(行下):a
#將 this is a test line 追加到 以test 開頭的行後面
sed ‘/^test/a\this is a test line’ file
sed -i ‘2a\this is a test line’ test.conf #第2行之後插入

#插入(行上)
#i\命令 將 this is a test line 追加到以test開頭的行前面
sed ‘/^test/i\this is a test line’ file
sed -i ‘5i\this is a test line’ test.conf

#下一個:n #如果test被匹配,則移動到匹配行的下一行,替換這一行的aa,變為bb,並列印該行,然後繼續 sed ‘/test/{ n; s/aa/bb/; }’ file

#轉換:y
#把1~10行內所有abcde轉變為大寫,注意,正則表示式元字元不能使用這個命令
sed ‘1,10y/abcde/ABCDE/’ file

#只顯示IP地址
ifconfig
ifconfig | egrep ‘inet’
ifconfig | egrep inet | grep -v inet6 | sed ‘s/^.inet//g’ | sed 's/netmask.$//g’

#去掉ssh配置檔案中的帶#行和空行
more /etc/ssh/sshd_config
more /etc/ssh/sshd_config | sed ‘s/#.*KaTeX parse error: Expected 'EOF', got '#' at position 42: …onfig | sed 's/#̲.*//g’ | sed '/^$/d


將/etc/passwd檔案拷貝一份,做以下練習:
1.刪除檔案每行的第一個字元

[[email protected] ~]# sed -n 's/^.//p' passwd | tail -3
yquota4:x:10014:10025::/app/home/myquota4:/bin/bash
yquota5:x:10015:10025::/app/home/myquota5:/bin/bash
pache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

2.刪除檔案每行的第二個字元

[[email protected] ~]# sed -r 's/^(.)(.)/\1/g' passwd | tail -3
mquota4:x:10014:10025::/app/home/myquota4:/bin/bash
mquota5:x:10015:10025::/app/home/myquota5:/bin/bash
aache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

3.刪除檔案每行的最後一個字元

[[email protected] ~]# sed -r 's/(.)(.)$/\1/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bas
myquota5:x:10015:10025::/app/home/myquota5:/bin/bas
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologi

4.刪除檔案每行的倒數第二個字元

[[email protected] ~]# sed -r 's/(.)(.)$/\2/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bah
myquota5:x:10015:10025::/app/home/myquota5:/bin/bah
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologn

5.刪除檔案每行的第二個單詞

[[email protected] ~]# sed -r 's/(^[^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)/\1\2\3/' passwd | tail -3
myquota4::10014:10025::/app/home/myquota4:/bin/bash
myquota5::10015:10025::/app/home/myquota5:/bin/bash
apache::48:48:Apache:/usr/share/httpd:/sbin/nologin

6.刪除檔案每行的倒數第二個單詞

[[email protected] ~]# sed -r 's/([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)$/\2\3\4/' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4://bash
myquota5:x:10015:10025::/app/home/myquota5://bash
apache:x:48:48:Apache:/usr/share/httpd://nologin

7.刪除檔案每行的最後一個單詞

[[email protected] ~]# sed -r 's/([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)$/\1\2\4/' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/
myquota5:x:10015:10025::/app/home/myquota5:/bin/
apache:x:48:48:Apache:/usr/share/httpd:/sbin/

8.交換每行的第一個字元和第二個字元

[[email protected] ~]# sed -r 's/^(.)(.)/\2\1/g' passwd | tail -3
ymquota4:x:10014:10025::/app/home/myquota4:/bin/bash
ymquota5:x:10015:10025::/app/home/myquota5:/bin/bash
paache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

9.交換每行的第一個字元和第二個單詞

[[email protected] ~]# sed -r 's/(^[^a-Z]*)(.)([a-Z]+)([^a-Z]+)([a-Z]+)/\1\5\3\4\2/g' passwd | tail -3
xyquota4:m:10014:10025::/app/home/myquota4:/bin/bash
xyquota5:m:10015:10025::/app/home/myquota5:/bin/bash
xpache:a:48:48:Apache:/usr/share/httpd:/sbin/nologin

10.交換每行的第一個單詞和最後一個單詞

[[email protected] ~]# sed -r 's/(^[^a-Z]*)([a-Z]+)([^a-Z]+)(.*)([^a-Z]+)([a-Z]+)([^a-Z]*$)/\1\6\3\4\5\2\7/' passwd | tail -3
bash4:x:10014:10025::/app/home/myquota4:/bin/myquota
bash5:x:10015:10025::/app/home/myquota5:/bin/myquota
nologin:x:48:48:Apache:/usr/share/httpd:/sbin/apache

11.刪除一個檔案中所有的數字

[[email protected] ~]# sed -r 's/[0-9]*//gp' passwd | tail -3
myquota:x::::/app/home/myquota:/bin/bash
apache:x:::Apache:/usr/share/httpd:/sbin/nologin
apache:x:::Apache:/usr/share/httpd:/sbin/nologin

12.刪除每行開頭的所有空格

[[email protected] ~]# sed -r 's/^[[:space:]]//g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

13.用製表符替換檔案中出現的所有空格

[[email protected] ~]# sed -r 's/[[:space:]]/\t/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

14.把所有大寫字母用括號()括起來

[[email protected] ~]# sed -r 's/[A-Z]/\(&\)/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:(A)pache:/usr/share/httpd:/sbin/nologin

15.列印每行3次

[[email protected] ~]# sed 'p;p' passwd | tail -6
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

16.隔行刪除

[[email protected] ~]# sed  '0~2 {=;d}' passwd | tail -5
30
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
32
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
34

17.把檔案從第12行到第23行復制到第32行後面

[[email protected] ~]# sed  '12h;13,23H;32G' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
david:x:10007:10012::/home/david:/bin/bash
peter:x:10008:10012::/home/peter:/bin/bash
jack:x:10009:10013::/home/jack:/bin/bash
mike:x:10010:10013::/home/mike:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
myquota1:x:10011:10025::/app/home/myquota1:/bin/bash
myquota2:x:10012:10025::/app/home/myquota2:/bin/bash
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

18.把檔案從第12行到第23行移動到第32行後面

[[email protected] ~]# sed  '12{h;d};13,23{H;d};32g' passwd     
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
david:x:10007:10012::/home/david:/bin/bash
peter:x:10008:10012::/home/peter:/bin/bash
jack:x:10009:10013::/home/jack:/bin/bash
mike:x:10010:10013::/home/mike:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
myquota1:x:10011:10025::/app/home/myquota1:/bin/bash
myquota2:x:10012:10025::/app/home/myquota2:/bin/bash
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

19.只顯示每行的第一個單詞

[[email protected] ~]# sed 's/\([a-Z]\+\)\([^a-Z]\+\)\(.*\)/\1/' /etc/passwd | tail -3  
myquota
myquota
apache

20.列印每行的第一個單詞和第三個單詞

[[email protected] ~]# sed 's/\([a-Z]\+\)\([^a-Z]\+\)\([a-Z]\+\)\([^a-Z]\+\)\([a-Z]\+\)\([^a-Z]\+\)\(.*\)/\1\t\5/' /etc/passwd | tail -3  
myquota app
myquota app
apache  Apache

21.將格式為 mm/yy/dd 的日期格式換成 mm;yy;dd

[[email protected] ~]# date '+%m/%y/%d' |sed 's#/#; #g'
10; 18; 31