- 論壇徽章:
- 0
|
本帖最后由 where27 于 2010-03-15 14:12 編輯
AWK one-line寫的非常之好,前些日子我嘗試翻譯了一下,對我自己的能力也有了一點(diǎn)提升,最近又看了一下Famous Sed One-Liners Explained,覺得sed的難度比awk有過之而無不及啊,一度非常崩潰,幸好堅(jiān)持了下去,加上一直在cu的shell版塊發(fā)帖子提問,在黑哥等人的幫助下,也算馬馬虎虎看完了,為了造福一下部分像我這種sed菜鳥,我將看過的這些內(nèi)容翻譯一下,請大家批評指正。謝謝!
先進(jìn)入第一部分:空行,編號,以及文本轉(zhuǎn)換
開始翻譯之前我想講一下sed程序的執(zhí)行流程,還是舉一個例子說明吧- #more file
- 123
- 456
- #sed ‘/5/p’ file
- 123
- 456
- 456
- # sed –n ‘/5/p’ file
- 456
復(fù)制代碼 和awk類似,sed 語句的基本結(jié)構(gòu)也是 sed ‘模式{動作1;動作2}’file 。同樣也是匹配模式才執(zhí)行動作。不過sed中有兩個空間大家一定要記住,一個叫pattern space(模式空間),一個叫hold buffer(緩沖區(qū)/緩沖空間),sed中的模式匹配的對象只是模式空間,而動作{p,d,n,g..etc}則的對象是模式空間和緩沖空間。和awk一樣,sed也是一行一行的讀入文本,不過sed在執(zhí)行命令前,會將文本的行讀到模式空間中,然后執(zhí)行模式{動作}語句,而在執(zhí)行命令完后,默認(rèn)sed還是把模式空間的內(nèi)容打印出來(通過-n 參數(shù)可以把最后默認(rèn)打印模式空間的動作取消)。在上面的例子中,首先sed把123讀入到模式空間中,由于模式/5/不匹配123,因此后面動作p(打印當(dāng)前模式空間的內(nèi)容)也就不執(zhí)行了,正如之前說的,sed在讀入下一行456之前會執(zhí)行默認(rèn)的打印動作p,把123打印出來。繼續(xù)讀下一行456,由于模式/5/匹配456,執(zhí)行動作p把456打印出來,而后默認(rèn)又打印了一次456。這就是sed命令的一個基本流程。當(dāng)然大多數(shù)情況下我們只是想要把匹配模式的內(nèi)容打印出來,這里加一個-n參數(shù)就可以了。
Tips:在sed讀入下一行前會把模式空間清空,所以當(dāng)讀第二行456的時候,模式空間內(nèi)的123已經(jīng)沒了。
一、 空行
1. 輸出兩倍行距文件這個例子使用了G命令,這個命令把緩沖空間的內(nèi)容附加到模式空間,由于沒有命令對緩沖空間做操作(只有h,H,x三個命令可以對緩沖空間做操作),所有緩沖空間的內(nèi)容一直為空,因此只是簡單的附加了一個換行符\n在模式空間后面,執(zhí)行完G以后,sed默認(rèn)執(zhí)行打印的動作將123\n打印出來,因此輸出的內(nèi)容里面就多了一個空行。
2. 輸出兩倍行距文件(文件有空行,非空行之間間隔不超過一個空行)- #more file
- 123
- 456
- #sed ‘/^$/d;G’ file
- 123
- 456
復(fù)制代碼 Sed中的只有匹配模式的行才執(zhí)行動作。這個例子中有兩個模式{動作}語句,第一個語句只有當(dāng)行匹配/^$/的時候才進(jìn)行操作,^$代表空行大家應(yīng)該都知道吧,sed對空行執(zhí)行動作d,這個命令的意思是刪除當(dāng)前模式空間的內(nèi)容,開始新的循環(huán)。怎么理解呢?其實(shí)就是把模式空間的空行清空以后,不再執(zhí)行后面的命令,也不執(zhí)行默認(rèn)的打印動作,而是返回到開頭,讀取下一行的內(nèi)容到模式空間,繼續(xù)執(zhí)行命令。所以說是開始新的循環(huán)。簡單來說就是讀到空行就把它刪除,然后重新讀取下一行。當(dāng)sed讀到非空行的時候,不匹配模式,因此不執(zhí)行d,G沒有模式限制,因此去執(zhí)行G,跟例1一樣,加一個空行在后面,打印出來,在繼續(xù)讀下一行,因此得到以上輸出。
3. 輸出3被行距這個沒什么好講的,兩次G,也就是附加兩個回車在文本的后面,打印出來。
4. 只打印奇數(shù)行文本- #more file
- 123
- 456
- 789
- abc
- #sed ‘n;d’ file
- 123
- 789
復(fù)制代碼 這里出現(xiàn)了一個新的命令n,命令n的作用是:打印當(dāng)前模式空間的內(nèi)容(如果前面加了參數(shù)-n則不打。,然后清空模式空間,把下一行讀入到模式空間中。然后執(zhí)行d,即刪除模式空間內(nèi)容,在回到開頭。所以大家可以發(fā)現(xiàn),打印出來的都是奇數(shù)行,而偶數(shù)行都被d刪除了。
5. 在匹配正則表達(dá)式/5/的行的前面插入一個空行- #sed ‘/5/{x;p;x}’ file
- 123
- 456
- 789
復(fù)制代碼 出現(xiàn)了一個新的命令x,之前講到x命令可以操作緩沖空間,具體就是把模式空間的內(nèi)容和緩沖空間的內(nèi)容交換,模式/5/只匹配第二行的456,因此對第一行和第三行,就是默認(rèn)打印出來而已,當(dāng)讀入456的時候,x將模式空間內(nèi)容的456與緩沖空間的內(nèi)容交換(默認(rèn)是空),接著把打印模式空間的空行,再執(zhí)行x,這個時候緩沖空間里有456,又把456還給模式空間,最后執(zhí)行默認(rèn)的打印動作,把456打印出來。
Tips:{x;p;x}是一個命令群組,匹配模式才按順序執(zhí)行他們。
6. 在匹配正則表達(dá)式/5/的行的后面插入一個空行- #sed ‘/5/G’ file
- 123
- 456
- 789
復(fù)制代碼 這個例子和第一個例子類似,只不過G只對456這行操作,因此只在第二行后面附加一個空行。
7. 在匹配正則表達(dá)式/5/所在行的前后兩行都加上一個空行這個例子其實(shí)就是5,6的合體,讀入456后,先執(zhí)行x;p打印出空行,然后執(zhí)行x;G,打印出456和空行,也就是在456的前后各有一個空行。
二、 編號
8. 給文本的每行編號,并把行號放在行的左邊- #sed = file|sed ‘N;s/\n/\t/’
- 1 123
- 2 456
- 3 789
復(fù)制代碼 有一點(diǎn)點(diǎn)復(fù)雜了,這個語句其實(shí)可以分成兩個,第一個使用了新的命令=,作用是直接把當(dāng)前行的行號打印出來,因?yàn)闆]有辦法直接把行號附加到模式空間去,所有才利用管道符號執(zhí)行第二個sed命令來實(shí)現(xiàn)這個功能。第二個sed又有了一個新的命令N,這個命令的作用就是附加一個\n和下一行的內(nèi)容到當(dāng)前的模式空間去,同樣s///命令也是sed中非常基本的一個命令,s/\n/\t/的作用是如果模式空間內(nèi)有\(zhòng)n,就把\n換成\t也就是制表符,然后再把模式空間的內(nèi)容打印出來
我們來看看這兩個命令分別執(zhí)行的過程執(zhí)行第一個sed = file后- #sed = file
- 1
- 123
- 2
- 456
- 3
- 789
復(fù)制代碼 第二個語句是針對第一個語句的輸出來做操作的,來看sed ‘N;s/\n/\t/’ ,首先模式空間內(nèi)容是1,N將換行\(zhòng)n和123附加到了1的后面,因此模式空間就變成了1\n456,s/\n/\t/則把換行符\n換成了制表符\t,由此模式空間就變成了1\t123,然后打印出來,其他依次類推,所以得到了以下內(nèi)容9. 給文本每行編號,并把行號右對齊。- #sed = file | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'
復(fù)制代碼 這個例子也包含了兩部分,第一部分跟例8一樣給每行編號,第二部分使用命令N把沒兩行的內(nèi)容連在一起,然后使用兩個替換命令把行號右對齊,第一個替換命令在行的開頭加上了5個空格,第二個替換命令在換行符\n前提取至少6個字符,然后把獲取的內(nèi)容和換行符用之前標(biāo)記的內(nèi)容\1在這里(\1指的是之前第一個被\(\)括起來的內(nèi)容,同理第二個被\(\)括起來的內(nèi)容可以用\2來代替,依次類推。。)和兩個空格代替,空格用來把行號和文本分隔開。
第二部分讀起來可能有點(diǎn)難懂,我們看一個例子,為了表達(dá)的更清晰,我們用@來代替\n,用-來代替空格。- # echo "-----12@contents" | sed 's/-*\(.\{6,\}\)@/\1--/'
- ----12--contents
復(fù)制代碼 這個正則表達(dá)式 ‘-*\(.\{6,\}\)@’ (或者只是 ‘-*(.{6,})@’) 匹配任意個-,然后是6個其他的字符,接著是一個符號@,sed
他們提取出來,并保存起來以供后面的\1調(diào)用。首先sed匹配一個-然后是緊接著的六個字符----12和@,接著s命令把之前匹配的內(nèi)容替換成\1(也就是之前保存起來的六個字符----12)和--.最終的結(jié)果就是把”-----12@”變成了”----12”.
10. 只給非空行編號- #more file
- 123
- 456
- 789
- # sed '/./=' file | sed '/./N; s/\n/ /'
- 1 123
- 2 456
- 4 789
復(fù)制代碼 這個例子也是分成了兩個部分,第一部分的輸出通過管道符|傳遞給第二部分當(dāng)做第二部分的輸入,第一部分使用正則表達(dá)式/./過濾出至少一個字符的行,當(dāng)sed把空行放入模式空間后,由于不匹配模式,因此也不對其執(zhí)行=這個編號的命令。第二部分和第八例題一樣也是把兩行合并成一行后,替換\n為空格,然后打印出來。
11. 計算文件的行數(shù)(類似wc –l的作用)這個sed例子使用了參數(shù)-n去修飾執(zhí)行的動作,-n使得在模式空間被處理完后,并不執(zhí)行默認(rèn)的p把模式空間內(nèi)容打印出來,想在在-n參數(shù)下輸出內(nèi)容,只能使用一些命令(=,a,I,i,p,P,c,r,w..etc),這個例子中,模式部分是$,匹配文件的最后一行,動作也=,也就是打印行號,因此輸出是最后一行的行號,也就是行的數(shù)量。
三、 文本替換
Sed one-liner中在這里介紹了很多關(guān)于windows格式文本轉(zhuǎn)為unix格式文本,大家要知道在windows下面是用兩個字符分行即回車+換行,而unix下只有一個換行,cu里相關(guān)的內(nèi)容有很多,我就不加介紹了。
12. 刪除每行的空白符(包括空格和制表符)- #more file
- 123
- 456
- 789
- #sed ‘s/^[ \t]*//’ file
- 123
- 456
- 789
復(fù)制代碼 這個很簡單,s將每行中匹配行首(^匹配行首)任意個空白的行,并把這些空白刪除,僅此而已。
13. 刪除每行結(jié)尾的空白行這個也沒什么好講的,匹配行尾有任意個空白的行,并把空白刪除
14. 同時刪除行首和行尾的空白- # sed 's/^[ \t]*//;s/[ \t]*$//' file
復(fù)制代碼 只是兩個例子的合體而已。
15. 每行的開頭添加兩個空白- #more file
- 123
- 456
- 789
- #sed ‘s/^/ /’ file
- 123
- 456
- 789
復(fù)制代碼 在行首的位置加上兩個空白,僅此而已。
16. 右對齊文本(文本寬度為21個字符)- # sed -e :a -e 's/^.\{1,20\}$/ &/;ta' file
- 123
- 456
- 789
復(fù)制代碼 這個例子中sed出現(xiàn)了一個新的參數(shù)-e,-e的作用是允許sed把一段語句分成若干部分,當(dāng)sed執(zhí)行命令前,會先將這些部分組合起來,再執(zhí)行命令。我們通常把一段sed分成若干部分是因?yàn)檫@些部分分別完成不同的功能,分開后比較容易讀懂。第一個部分的命令之前大家也沒有見過,是一個冒號和a,作用是創(chuàng)建一個名字叫a的標(biāo)簽。第二部分sed使用了一個新的命令t,t的作用是如果前一個s/../../命令執(zhí)行成功,那么sed將跳轉(zhuǎn)到指定的標(biāo)簽,這里ta也就是跳轉(zhuǎn)到之前的標(biāo)簽a這里,這個:a .s/../../.ta,構(gòu)成了一個循環(huán),也就是說只要模式空間的內(nèi)容能夠執(zhí)行s/../../替換命令,sed就通過t把替換后的文本再重新執(zhí)行替換,周而復(fù)始,直到模式空間的內(nèi)容不滿足s/../../的匹配要求,才終止循環(huán),打印出模式空間的內(nèi)容。
下面來看一下替換命令s/^.\{1,19\}$/ &/,其中^.\{1,19\}$匹配包含1個或19個字符的行,后面的&則是代表前一個模式中的內(nèi)容,也就是.\{1,19\},簡單說就是,當(dāng)模式空間的內(nèi)容是1個或19個字符的時候,就在模式空間的內(nèi)容前面加上一個空格,如果前面的循環(huán)大家看的懂的話,就可以可以看懂這個例子了:就是把每行的內(nèi)容前面加上一個個的空白,直到這行的長度超過了19個字符,當(dāng)文本寬度是20個字符的時候,sed就不再加空格了,直接打印出文本。
類似一個while循環(huán)- # while (str.length() <= 21) {
- str = " " + str
- }
復(fù)制代碼 17. 文本居中(寬度為21字符)- # sed -e :a -e 's/^.\{1,20\}$/ & /;ta' file
- 123
- 456
- 789
復(fù)制代碼 這個例子很前一個幾乎一樣,不同的是在添加空格的時候,左右都添加了,當(dāng)文本的長度達(dá)到21個字符的時候,前后的空白字符的個數(shù)也一樣,也就達(dá)到了文本居中的目的了。
18. 替換文本每行中第一次出現(xiàn)的1為a- #more file
- 123123123
- 456
- 789
- #sed ‘s/1/a/’ file
- a23123123
- 456
- 789
復(fù)制代碼 一個簡單的替換語句,把文本中每行的第一個1替換成a
19. 替換每行出現(xiàn)的第二個1為a- #sed ‘s/1/a/2’ file
- 123a23123
- 456
- 789
復(fù)制代碼 其實(shí)這才是替換語句的完成格式,把每行中出現(xiàn)的第二個1替換成a,沒有這個2的話,sed默認(rèn)為1,也就是上一題的匹配第一個出現(xiàn)的1
20. 把所有行中的1替換成a- #sed ‘s/1/a/g’ file
- a23a23a23
- 456
- 789
復(fù)制代碼 這里使用了另一個位置參數(shù)g,代表所有,也就是把所有的1都替換成a
21. 如果一個行出現(xiàn)了2個1,則替換第一個1為a- #more file
- 123123
- 4561
- 789
- #sed ‘s/\(.*\)1\(.*1\)/\1a\2/’ file
- a23123
- 4561
- 789
復(fù)制代碼 作用大家都很清楚了,只是在s替換語句中出現(xiàn)了2個組\(..\),第一個組里包含了在第一個1前面的所有字符,而第二個組里包含了從第一個1后到第二個1截止(包含第二個1)的所有字符。因此這個替換語句的模式中包含了2個1,但只是替換第一個1為a,這也是為什么在第二行中也有1,為什么不會被替換成a的原因,因?yàn)榈诙兄挥幸粋1,不匹配s替換語句中的模式。
22. 替換每行中最后一次出現(xiàn)的1為a- #sed ‘s/\(.*\)1/a/’ file
- 123a23
- 4561
- 789
復(fù)制代碼 同樣使用了字符組,匹配的是1前面的所有字符,之所以會把最后出現(xiàn)的1替換成a,是因?yàn)?*是最大匹配,比如說在第一行123123中,.*1能匹配1,和1231,但是默認(rèn)匹配最大也就是1231,因此替換的是最后一個1.
23. 在包含6的行中把所有1都替換成a- #sed ‘/6/s/1/a/g’ file
- 123123
- 456a
- 789
復(fù)制代碼 改例子使用了一個正則表達(dá)式/6/去限制替換命令的使用,也就是說只有匹配6的行才能夠執(zhí)行替換。
24. 在不含6的行中把所有1都替換成6- #sed ‘/6/!s/1/a/g’ file
- a23a23
- 4561
- 789
復(fù)制代碼 Sed可以使用反向匹配,也就是不匹配的行執(zhí)行動作,在這里,不匹配6的第一行中的1都被換成了a,第二行中有6,所以不把1換成a
25. 替換1或者6或者9為a- #sed ‘s/1/a/g;s/6/a/g;s/9/a/g’ file
- a23a23
- 45aa
- 78a
復(fù)制代碼 這里使用了3個s替換語句去匹配和替換。如果你用的是gnu版本的sed,就可以用下面的語句- #sed ‘s/1|6|9/a/g’ file
- a23a23
- 45aa
- 78a
復(fù)制代碼 Sed提供了更高級的正則表達(dá)式功能包含了間隔符|,這里的1\|6\|9就是表示匹配1或者6或者9
26. 倒序文本(類似tac的作用)- #more file
- 123
- 456
- 789
- #sed ‘1!G;h;$!d’ file
- 789
- 456
- 123
復(fù)制代碼 終于到了一個稍微有點(diǎn)難度的例子了,首先我們來解釋一個這個命令,G:前面講過,就是把緩沖區(qū)的內(nèi)容附加在模式空間的后面(以\n分隔)。h:將模式空間的內(nèi)容把緩沖區(qū)的內(nèi)容覆蓋,這時候緩沖區(qū)的內(nèi)容和模式空間一樣了d:當(dāng)然就是把模式空間的內(nèi)容刪除,并返回到開頭。我們來逐行看一下
第一行:1!G的意思是出了第一行其他行都執(zhí)行G,因此跳過,直接到h,把模式空間的內(nèi)容拷到緩沖區(qū)中,緩沖區(qū)中的內(nèi)容是123接著執(zhí)行d,返回到了開頭,繼續(xù)讀下一行456
第二行:第二行可以執(zhí)行G命令,即把緩沖區(qū)123的內(nèi)容附加到模式空間中456的后面,并以\n分隔,因此模式空間的內(nèi)容為456\n123,h后,緩沖區(qū)的內(nèi)容也變成了456\n123,同樣d后,什么都不輸出直接到下一行
第三行:執(zhí)行G,附加緩沖區(qū)的456\n123到789的后面,及模式空間變成789\n456\n123,同時緩沖區(qū)通過h也變成了789\n456\n123,最后的$!d的意思是最后一行不執(zhí)行d的動作,也就是命令到此結(jié)束了,sed默認(rèn)把模式空間的789\n456\n123打印出來,也就是大家看到的結(jié)果了,下面的流程可以幫助大家理解。
讀入文本 命令 模式空間 緩沖空間 打印結(jié)果
123 1!G 123 空 空
h 123 123 空
$!d 空 123 空
456 1!G 456\n123 123 空
h 456\n123 456\n123 空
$!d 空 456\n123 空
789 1!G 789\n456\n123 456\n123 空
h 789\n456\n123 789\n456\n123 空
$!d 789\n456\n123 789\n456\n123 789\n456\n123
最后打印出來的789\n456\n123也就是我們要的結(jié)果了。
另一種寫法- # sed -n '1!G;h;$p' file
- 789
- 456
- 123
復(fù)制代碼 -n防止sed默認(rèn)的p動作,而只在最后一行的時候把模式空間的東西打印出來
指的一提的是,這個例子會在執(zhí)行的過程中會使用大量的內(nèi)存,因?yàn)樗诖蛴〕龅剐虻奈谋局鞍颜麄文件的內(nèi)容都保存在緩沖區(qū)里面,所以如果文件的行數(shù)過多的話,還是不要使用這個語句吧。
27. 翻轉(zhuǎn)每行的內(nèi)容(類似rev的作用)- # sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//' file
- 321
- 654
- 987
復(fù)制代碼 這個命令的結(jié)構(gòu)非常復(fù)雜,可以把它分成4個部分- #sed '
- /\n/!G
- s/\(.\)\(.*\n\)/&\2\1/
- //D
- s/.//
- '
復(fù)制代碼 我們一個個來分析,以第一行123為例
/\n/!G:如果模式空間的內(nèi)容不包括\n,把緩沖區(qū)的內(nèi)容附加到模式空間后,以\n分隔,緩沖區(qū)的內(nèi)容為空除非有命令對其進(jìn)行操作,這樣執(zhí)行過后模式空間的內(nèi)容變成123\n
s/\(.\)\(.*\n\)/&\2\1/:s替換的模式部分包含了2個字符組,字符組1只包含了1個任意字符,第二個字符組包括了剩余的字符和\n,&代表的是前面整個匹配項(xiàng),也就是123\n,例如,在執(zhí)行完這個語句后,模式空間的內(nèi)容123\n就變成了123\n23\n1
//D:這個語句是整個sed例子的關(guān)鍵,一個空的匹配//,表示匹配上一個出現(xiàn)的正則表達(dá)式,這里也就是/\(.\)\(.*\n\)/D了,D的作用是刪除模式空間中從開始到第一個\n截止的字符,并從第一個命令開始重新執(zhí)行sed(不讀到下一行)。實(shí)際上是創(chuàng)建了一個循環(huán),也就是只要模式空間的\n前面有一個字符,就把\n和前面的字符刪除,剩余的內(nèi)容傳遞到第一個命令繼續(xù)執(zhí)行,只有\(zhòng)n前面沒有字符了,循環(huán)才結(jié)束。
S/.//:意思很簡單,刪除模式空間的第一個字符,但是這個命令執(zhí)行的條件就是D不執(zhí)行,也就是說模式空間中\(zhòng)n前面沒有字符,后面后經(jīng)過翻轉(zhuǎn)后的內(nèi)容,其實(shí)就是把\n給刪除了,接著默認(rèn)sed輸出翻轉(zhuǎn)后的內(nèi)容,還是來看一下流程吧
讀入文本 命令 模式空間 緩沖空間 打印結(jié)果
123 /\n/!G 123\n 空 空
s/\(.\)\(.*\n\)/&\2\1/ 123\n23\n1 空
//D 23\n1 空 空
D執(zhí)行成功,循環(huán)到開頭執(zhí)行/\n/!G
/\n/!G 23\n1 空 空
s/\(.\)\(.*\n\)/&\2\1/ 23\n3\n21 空 空
//D 3\n21 空 空
D執(zhí)行成功,循環(huán)到開頭執(zhí)行/\n/!G
/\n/!G 3\n21 空 空
s/\(.\)\(.*\n\)/&\2\1/ 3\n\n321 空 空
//D \n321 空 空
D執(zhí)行成功,循環(huán)到開頭執(zhí)行/\n/!G
/\n/!G \n321 空 空
s/\(.\)\(.*\n\)/&\2\1 \n321 空 空
//D \n321 空 空
模式不匹配,開始執(zhí)行s/.// 321 空 321
把321打印出來了,累死我了。。
28. 把文本兩行合成一行- #more file
- 123
- 456
- 789
- abc
- #sed ‘$!N;s/\n/ /’ file
- 123 456
- 789 abc
復(fù)制代碼 這個例子使用N將兩個連續(xù)的行組合成一個新行,他們之間通過\n連接,因此第二個替換語句將\n換成空格,就得到了輸出,由于最后一行沒有下一行可以連接,所以N的前面是$!
29. 如果行的結(jié)尾是\,就把下一行附加到這一行末尾。- #more file
- 123\
- 456\
- 789
- abc
- #sed –e :a–e ‘/\\$/N;s/\\\n/ /;ta’
- 123 456 789
- abc
復(fù)制代碼 第一個命令:a,創(chuàng)建了一個標(biāo)簽a,而第二個命令判斷模式空間的內(nèi)容是否是以\結(jié)尾,如果是,則執(zhí)行N把\n和下一行附加到這行的結(jié)尾,然后執(zhí)行s替換,把中間的\\n換成空格,如果成功,則ta把模式空間的內(nèi)容循環(huán)到標(biāo)簽的位置繼續(xù)處理,也就是判斷附加的那行是否還是以\結(jié)尾,如果是,繼續(xù)附加,循環(huán)下去。如果不是,打印出模式空間的內(nèi)容。
Tips:如果沒有這個循環(huán)的話,就不能檢查每一行的結(jié)尾是否是\.
30. 如果行的開頭是=,就把這行附加到上一行的結(jié)尾。- #more file
- 123
- =456
- =789
- abc
復(fù)制代碼- #sed –e :a –e ‘$!N;s/\n=/ /;ta’ –e ‘P;D’ file
- 123 456 789
- abc
復(fù)制代碼 這個例子的開頭也創(chuàng)建了一個標(biāo)簽a,然后檢測文本是不是最后一行,如果不是就把下一行附加到這一行的結(jié)尾,以\n分隔,如果正好下一行的開頭是=,則使用替換命令s把換行符\n和=替換成一個空格,如果替換成功,則ta把命令循環(huán)至標(biāo)簽a的位置,然后繼續(xù)附加下一行,檢查下一行是否是以=開頭,是的話就替換,依次循環(huán),知道下一行的開頭不是=,則循環(huán)結(jié)束,開始執(zhí)行后面的命令P;D,P的意思是打印模式空間中從一個字符到第一個\n為止的所有字符,D的意思是刪除第一個字符到\n截止的所以字符,其實(shí)也就是刪除剛才打印過的字符,然后回到開頭。繼續(xù)讀下一行
上面的例子中,第一行和第二行第三行之所以連在了一起,就是因?yàn)榈诙泻偷谌惺且?開頭。
31. 將數(shù)字組以千分位的方式分成串- #echo "1234567"|sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'
- 1,234,567
復(fù)制代碼 這個例子首先創(chuàng)建一個標(biāo)簽a,然后模式替換部分分成了兩個組,第一個組在最后3個數(shù)字之前是任意個字符加上一個數(shù)字,第二個組是最后的三個數(shù)字,替換的結(jié)果是在兩組之間加上一個逗號,然后又是循環(huán)開始,知道所有的數(shù)字都3個一組的被逗號分隔。
看看上面的例子,第二個組里包含的是數(shù)字1234,第二個組里包含的是567,加上逗號后變成1234,567
由于替換成功,循環(huán)開始,這次第一個組里包含的是1,第二個組里包含的是234,替換過后,1234,567就變成了1,234,567,接著循環(huán),由于1,234,567中沒有連續(xù)的四個數(shù)字,所有替換不成立,sed默認(rèn)打印出模式空間的內(nèi)容,也就是1,234,567。
如果sed的版本是gnu的,則可以簡寫成- #echo "1234567"|sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'
- 1,234,567
復(fù)制代碼 不同的地方在于包含3個數(shù)字的字符組是如何匹配的。重點(diǎn)在于這個\B,它是一個位置字符,不占空間,匹配任何地方但是不包含字符分界線如空格,分號,逗號,冒號等而最后的\>,匹配的是單詞的分界如逗號。
32. 每2行加一個空行- #more file
- 123
- 456
- 789
- abc
- #sed ‘n;G’ file
- 123
- 456
- 789
- abc
復(fù)制代碼 前講過,n命令的作用是打印當(dāng)前行,然后清空,把下一行讀入,G把一個空行加到了下一行的結(jié)尾,這樣也就是打印了兩行之后在打印一個空行了。
GNU版本的sed還有另一種寫法- #sed ‘0~2G’ file
- 123
- 456
- 789
- abc
復(fù)制代碼 這個其實(shí)也好理解,就是從還沒有讀入行開始,也就是0行,每過兩行就執(zhí)行一個G,也就是添加一個空行,大家記住這個格式就可以了。
好了第一部分完成了,加油! |
|