- 論壇徽章:
- 0
|
ubuntu@ubuntu:~$ sed '/Public/R a' dat #R(read file),執(zhí)行到包含Public的行時,
1 dat #從文件a中讀入一行數(shù)據(jù)
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
@@@@@@@@ hello
9 Templates
10 Videos
命令:/b/t/T
:A,創(chuàng)建label A;
b A,跳轉(zhuǎn)到label A處繼續(xù)執(zhí)行sed命令;
t A,本模式空間中,如果s///替換成功過,就跳轉(zhuǎn)到label A處繼續(xù)執(zhí)行sed命令;沒有替換成功,不執(zhí)行跳轉(zhuǎn);
T A,跟t相反,本模式空間中,如果沒有s///替換成功過,就跳轉(zhuǎn)到label A處繼續(xù)執(zhí)行sed命令;替換成功,不執(zhí)
行跳轉(zhuǎn);
以上三個跳轉(zhuǎn)命令,如果沒有跟label,且符合跳轉(zhuǎn)條件時,都跳到腳本結(jié)尾;
ubuntu@ubuntu:~$ cat dat
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/\<[dD]/b A #遇到包含以d或D開頭的單詞的行,就跳到A處把
/\<[P]/p #包含以d開頭的單詞的行打印出來
:A #同時打印包含以P開頭的單詞的行
/\<[d]/p #
' dat #相當(dāng)于 if (包含 d/D開頭的單詞)
1 dat # goto A
3 dir1 # else if (P開頭)
7 Pictures # 打印
8 Public # :A 打印d開頭的單詞所在的行
ubuntu@ubuntu:~$ sed -n '/\<[dD]/b # 遇到包含以d或D開頭的單詞的行,
/\<[P]/p #跳轉(zhuǎn)到腳本結(jié)尾
:A #打印包含以P開頭的單詞的行
/\<[d]/p
' dat
7 Pictures
8 Public
# 命令t
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; t A #如果dir替換成功,
/dir/a\***** #就跳到:A處,打印出來
:A #否則順序執(zhí)行下面的腳本
/\<[d]/p
' dat
1 dat
3 dir@@@@@@1
4 dir@@@@@@2
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; t A #DIR沒有替換成功,就不跳轉(zhuǎn),
/dir/a\***** #順序執(zhí)行下面的腳本
:A
/\<[d]/p
' dat
1 dat
3 dir1
*****
4 dir2
*****
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; t #如果dir替換成功,
/dir/a\***** #就跳到腳本結(jié)尾,不打印出來
:A
/\<[d]/p
' dat
1 dat
ubuntu@ubuntu:~$ sed -n -r 's/DIR/dir@@@@@@/; t #DIR沒有替換成功,就不跳轉(zhuǎn),
/dir/a\***** #順序執(zhí)行下面的腳本
:A
/\<[d]/p
' dat
1 dat
3 dir1
*****
4 dir2
*****
#命令T
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; T A #dir替換成功,不跳轉(zhuǎn),
/dir/a\***** #順序執(zhí)行下面的腳本
:A #在包含dir的行后添加*****
/\<[d]/p
' dat
1 dat
3 dir@@@@@@1
*****
4 dir@@@@@@2
*****
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; T A #DIR沒有替換成功,跳轉(zhuǎn)到A,
/dir/a\***** #打印出包含[以d開頭的字母]的行
:A
/\<[d]/p
' dat
1 dat
3 dir1
4 dir2
ubuntu@ubuntu:~$ sed -n 's/dir/dir@@@@@@/; T #dir替換成功,不跳轉(zhuǎn),
/dir/a\***** #順序執(zhí)行下面的腳本
:A
/\<[d]/p
' dat
3 dir@@@@@@1
*****
4 dir@@@@@@2
*****
ubuntu@ubuntu:~$ sed -n 's/DIR/dir@@@@@@/; T #DIR沒有替換成功,
/dir/a\***** #跳轉(zhuǎn)到腳本結(jié)尾,不打印任何行
:A
/\<[d]/p
' dat
# 命令n/N, d/D
多行Next(N)命令是相對于next(n)命令的,
n(next)命令將模式空間中的內(nèi)容輸出,清空模式空間,然后讀入下一行,然后繼續(xù)執(zhí)行sed腳本(并不會轉(zhuǎn)移到腳本開頭)
N(Next)命令則保存原來模式空間中的內(nèi)容,再把新的一行讀入,兩者之間依靠一個換行符"\n"來分隔,然后繼續(xù)執(zhí)行sed腳本。
ubuntu@ubuntu:~$ cat dat
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/Documents/n #遇到Documents所在的行,輸出模式空間(因為使用
/M/p #了n選項,并不會輸出),清空模式空間,讀入下一行
' dat #讀入的內(nèi)容中剛好包含了”M”,就打印出來
6 Music
ubuntu@ubuntu:~$ sed -n '/Documents/N #遇到Documents所在的行,把下一行數(shù)據(jù)添加在
/M/p #模式空間后面(兩行之間自動添加\n分隔),
' dat #現(xiàn)在模式空間包含”M”, 打印模式空間
5 Documents #p打印整個模式空間,
6 Music #P打印模式空間第一個\n前的內(nèi)容
ubuntu@ubuntu:~$ sed -n '/Documents/{ #遇到Documents所在的行,把下一行數(shù)據(jù)添加在
N #模式空間后面(兩行之間自動添加\n分隔),
d} #刪除模式空間內(nèi)容,
/Music/p
' dat
ubuntu@ubuntu:~$ sed -n '/Documents/{ #遇到Documents所在的行,把下一行數(shù)據(jù)添加在
N #模式空間后面(兩行之間自動添加\n分隔),
D} #刪除模式空間中第一個\n前的內(nèi)容,
/Music/p #打印模式空間
' dat
6 Music
前面我們說過,sed執(zhí)行其實就是個大循環(huán),每次對一行數(shù)據(jù)進(jìn)行操作,一行一行的將所有的數(shù)據(jù)處理完。
對每一行操作,sed有4個步驟:
1、讀入當(dāng)前行數(shù)據(jù)
2、對其執(zhí)行sed命令
3、輸出模式空間的內(nèi)容(除非-n限制了自動輸出)
4、清空模式空間
# 命令h/H, g/G
h/H 將模式空間的內(nèi)容copy(覆蓋原有內(nèi)容)/append到存儲空間
g/G 將存儲空間的內(nèi)容copy(覆蓋原有內(nèi)容)/append到模式空間
H(Hold)/G(Get),都會在目的空間的原有內(nèi)容之后加上一個換行符“\n”,然后才把源空間中的內(nèi)容加到換行符的后面。
ubuntu@ubuntu:~$ sed -n '/dir/{h;d} #將dir所在的行copy到(覆蓋)存儲空間(dir有兩次)
/Doc/{g;p}' dat #在Doc這一行,取出存儲空間的內(nèi)容,覆蓋模式空間
4 dir2 #打印模式空間
ubuntu@ubuntu:~$ sed -n '/dir/{h;d} #將dir所在的行copy到(覆蓋)存儲空間(dir有兩次)
/Doc/{G;p}' dat #在Doc這一行,取出存儲空間的內(nèi)容,附加在模式空間
5 Documents #打印模式空間
4 dir2
ubuntu@ubuntu:~$ sed -n '/dir/{H;d} #將dir所在的行附加到存儲空間(dir有兩次)
/Doc/{g;p}' dat #在Doc這一行,取出存儲空間的內(nèi)容,覆蓋模式空間
#注意,這個空行不是我手動換的,是本命令的輸出哦
3 dir1
4 dir2
ubuntu@ubuntu:~$ sed -n '/dir/{H;d} #將dir所在的行附加到存儲空間(dir有兩次)
/Doc/{G;p}' dat #在Doc這一行,取出存儲空間的內(nèi)容,附加在模式空間
5 Documents #打印模式空間
#怎么也有個空行?
3 dir1
4 dir2
ubuntu@ubuntu:~$ cat dat # 命令x,交換模式空間和存儲空間的內(nèi)容
1 dat
2 Desktop
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed '/Doc/{h;d} #遇到包含Doc的行,就把模式空間的內(nèi)容
/Pic/x #放進(jìn)存儲空間,然后刪除模式空間;
' dat #這樣Doc所在的行,是不會顯示出來的
1 dat
2 Desktop #所以第4行后直接就是第6行
3 dir1
4 dir2
6 Music
5 Documents #遇到包含Pic的行(第7行)后,交換模式空間和
8 Public #存儲空間的內(nèi)容,
9 Templates
10 Videos
下面的例子中請注意命令p/l/P的差別
ubuntu@ubuntu:~$ sed -n '/\<D/{N;p}' dat #遇到包含以D開頭的單詞的行,
2 Desktop #就讀取下一行到模式空間, 然后打印模式空間
3 dir1
5 Documents
6 Music
ubuntu@ubuntu:~$ sed -n '/\<D/{N;l}' dat #l,以可見(visually unambiguous)的方式
2 Desktop\n3 dir1$ #查看模式空間的內(nèi)容,
5 Documents\n6 Music$ #模式空間的內(nèi)容實際上是左邊這個樣子的
ubuntu@ubuntu:~$ sed -n '/\<D/{N }' dat #P,打印模式空間中第一個換行符號之前的內(nèi)容
2 Desktop
5 Documents
[ubuntu@bourne ~]$ cat dat1
hello Tom, hello Michel, hello Sara
hello Bourne, hello Ellen, hello Marco
[ubuntu@bourne ~]$ sed 's/hello/hi/' dat1 #將每個模式空間(行)中第一個hello替換為hi
hi Tom, hello Michel, hello Sara
hi Bourne, hello Ellen, hello Marco
[ubuntu@bourne ~]$ sed 's/hello/hi/g' dat1 #g(global),
hi Tom, hi Michel, hi Sara #將每個模式空間(行)中所有的hello替換為hi
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's#hello#hi#g' dat1 #s#...#...#g 可以用別的分割符號
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's hello hi g' dat1 #s ... ... g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's-hello-hi-g' dat1 #s-...-...-g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
[ubuntu@bourne ~]$ sed 's)hello)hi)g' dat1 #s)...)...)g
hi Tom, hi Michel, hi Sara
hi Bourne, hi Ellen, hi Marco
ubuntu@ubuntu:~$ sed -n -r '/Pub/{N #將模式空間的內(nèi)容寫入文件b
w b #遇到包含Pub的行時,將下一行的內(nèi)容添加到模式空間
}' dat #模式空間的內(nèi)容為:8 Public\n9 Templates
ubuntu@ubuntu:~$ cat b
8 Public
9 Templates
ubuntu@ubuntu:~$ sed -n -r '/Pub/{N #將模式空間中第一個換行符號之前的內(nèi)容寫入文件b
W b
}' dat
ubuntu@ubuntu:~$ cat b
8 Public
#大小寫轉(zhuǎn)換的經(jīng)典用法
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' dat
1 DAT #y,直譯,將[a-z]依次替換為[A-Z],
2 DESKTOP #本例將小寫字母全部轉(zhuǎn)換為大寫字母
3 DIR1
4 DIR2
5 DOCUMENTS
6 MUSIC
7 PICTURES
8 PUBLIC
9 TEMPLATES
10 VIDEOS
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/qazxswedcvfrtgbnhyujmkiolp/' dat
1 xqj #將[a-z]依次替換為[qazxsw...olp]
2 Dsufjbn #這樣就成了一個簡單的加密器
3 xcy1 #y/明文串/密文串/
4 xcy2 #注意,明文串和密文串中都不能出現(xiàn)相同的字母、
5 Dbzmtsgju #數(shù)字、符號,前后兩個串的長度要相等
6 Mmucz
7 Pczjmysu
8 Pmarcz
9 Tstnrqjsu
10 Vcxsbu
ubuntu@ubuntu:~$ sed 'y/abcdefghijklmnopqrstuvwxyz/qazxswedcvfrtgbnhyujmkiolp/' dat > tmp
ubuntu@ubuntu:~$ sed 'y/qazxswedcvfrtgbnhyujmkiolp/abcdefjhijklmnopqrstuvwxyz/' tmp
1 dat #將明文串和密文串交換位置,就成了解碼器
2 Desktop #y/密文串/明文串/
3 dir1
4 dir2
5 Documents
6 Music
7 Pictures
8 Public
9 Templates
10 Videos
ubuntu@ubuntu:~$ sed -n '/\w{3}[12]{1}/p' dat
ubuntu@ubuntu:~$ sed -n -r '/\w{3}[12]{1}/p' dat # r,使用擴(kuò)展正則表達(dá)式時,要加-r選項
3 dir1
4 dir2
|
|