亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 轉(zhuǎn):通用線程 -- sed 實(shí)例,第 2 部分 [打印本頁(yè)]

作者: cuci    時(shí)間: 2005-04-07 08:44
標(biāo)題: 轉(zhuǎn):通用線程 -- sed 實(shí)例,第 2 部分
sed 是很有用(但常被遺忘)的 UNIX 流編輯器。在以批處理方式編輯文件或以有效方式創(chuàng)建 shell 腳本來(lái)修改現(xiàn)有文件方面,它是十分理想的工具。本文是前一篇介紹 sed 文章的續(xù)篇。

替換!
讓我們看一下 sed 最有用的命令之一,替換命令。使用該命令,可以將特定字符串或匹配的規(guī)則表達(dá)式用另一個(gè)字符串替換。下面是該命令最基本用法的示例:

$ sed -e 's/foo/bar/' myfile.txt
上面的命令將 myfile.txt 中每行第一次出現(xiàn)的 'foo'(如果有的話)用字符串 'bar' 替換,然后將該文件內(nèi)容輸出到標(biāo)準(zhǔn)輸出。請(qǐng)注意,我說(shuō)的是每行第一次出現(xiàn),盡管這通常不是您想要的。在進(jìn)行字符串替換時(shí),通常想執(zhí)行全局替換。也就是說(shuō),要替換每行中的所有出現(xiàn),如下所示:

$ sed -e 's/foo/bar/g' myfile.txt
在最后一個(gè)斜杠之后附加的 'g' 選項(xiàng)告訴 sed 執(zhí)行全局替換。

關(guān)于 's///' 替換命令,還有其它幾件要了解的事。首先,它是一個(gè)命令,并且只是一個(gè)命令,在所有上例中都沒(méi)有指定地址。這意味著,'s///' 還可以與地址一起使用來(lái)控制要將命令應(yīng)用到哪些行,如下所示:

$ sed -e '1,10s/enchantment/entrapment/g' myfile2.txt
上例將導(dǎo)致用短語(yǔ) 'entrapment' 替換所有出現(xiàn)的短語(yǔ) 'enchantment',但是只在第一到第十行(包括這兩行)上這樣做。

$ sed -e '/^$/,/^END/s/hills/mountains/g' myfile3.txt
該例將用 'mountains' 替換 'hills',但是,只從空行開始,到以三個(gè)字符 'END' 開始的行結(jié)束(包括這兩行)的文本塊上這樣做。

關(guān)于 's///' 命令的另一個(gè)妙處是 '/' 分隔符有許多替換選項(xiàng)。如果正在執(zhí)行字符串替換,并且規(guī)則表達(dá)式或替換字符串中有許多斜杠,則可以通過(guò)在 's' 之后指定一個(gè)不同的字符來(lái)更改分隔符。例如,下例將把所有出現(xiàn)的 /usr/local 替換成 /usr:

$ sed -e 's:/usr/local:/usr:g' mylist.txt
在該例中,使用冒號(hào)作為分隔符。如果需要在規(guī)則表達(dá)式中指定分隔符字符,可以在它前面加入反斜杠。

規(guī)則表達(dá)式混亂
目前為止,我們只執(zhí)行了簡(jiǎn)單的字符串替換。雖然這很方便,但是我們還可以匹配規(guī)則表達(dá)式。例如,以下 sed 命令將匹配從 '<' 開始、到 '>' 結(jié)束、并且在其中包含任意數(shù)量字符的短語(yǔ)。下例將刪除該短語(yǔ)(用空字符串替換):

$ sed -e 's/<.*>//g' myfile.html
這是要從文件除去 HTML 標(biāo)記的第一個(gè)很好的 sed 腳本嘗試,但是由于規(guī)則表達(dá)式的特有規(guī)則,它不會(huì)很好地工作。原因何在?當(dāng) sed 試圖在行中匹配規(guī)則表達(dá)式時(shí),它要在行中查找最長(zhǎng)的匹配。在我的前一篇 sed 文章中,這不成問(wèn)題,因?yàn)槲覀兪褂玫氖?'d' 和 'p' 命令,這些命令總要?jiǎng)h除或打印整行。但是,在使用 's///' 命令時(shí),確實(shí)有很大不同,因?yàn)橐?guī)則表達(dá)式匹配的整個(gè)部分將被目標(biāo)字符串替換,或者,在本例中,被刪除。這意味著,上例將把下行:

<b>This</b> is what <b>I</b> meant.
變成:

meant.
我們要的不是這個(gè),而是:

This is what I meant.
幸運(yùn)的是,有一種簡(jiǎn)便方法來(lái)糾正該問(wèn)題。我們不輸入“'<' 字符后面跟有一些字符并以 '>' 字符結(jié)束”的規(guī)則表達(dá)式,而只需輸入一個(gè)“'<' 字符后面跟有任意數(shù)量非 '>' 字符并以 '>' 字符結(jié)束”的規(guī)則表達(dá)式。這將與最短、而不是最長(zhǎng)的可能性匹配。新命令如下:

$ sed -e 's/<[^>]*>//g' myfile.html
在上例中,'[^>]' 指定“非 '>'”字符,其后的 '*' 完成該表達(dá)式以表示“零或多個(gè)非 '>' 字符”。對(duì)幾個(gè) html 文件測(cè)試該命令,將它們管道輸出到 "more",然后仔細(xì)查看其結(jié)果。

更多字符匹配
'[ ]' 規(guī)則表達(dá)式語(yǔ)法還有一些附加選項(xiàng)。要指定字符范圍,只要字符不在第一個(gè)或最后一個(gè)位置,就可以使用 '-',如下所示:

'[a-x]*'
這將匹配零或多個(gè)全部為 'a'、'b'、'c'...'v'、'w'、'x' 的字符。另外,可以使用 '[]' 字符類來(lái)匹配空格。以下是可用字符類的相當(dāng)完整的列表:

字符類 描述
[] 字母數(shù)字 [a-z A-Z 0-9]
[] 字母 [a-z A-Z]
[] 空格或制表鍵
[] 任何控制字符
[] 數(shù)字 [0-9]
[] 任何可視字符(無(wú)空格)
[] 小寫 [a-z]
[] 非控制字符
[] 標(biāo)點(diǎn)字符
[] 空格
[] 大寫 [A-Z]
[] 十六進(jìn)制數(shù)字 [0-9 a-f A-F]

盡可能使用字符類是很有利的,因?yàn)樗鼈兛梢愿玫剡m應(yīng)非英語(yǔ) locale(包括某些必需的重音字符等等).

高級(jí)替換功能
我們已經(jīng)看到如何執(zhí)行簡(jiǎn)單甚至有些復(fù)雜的直接替換,但是 sed 還可以做更多的事。實(shí)際上可以引用匹配規(guī)則表達(dá)式的部分或全部,并使用這些部分來(lái)構(gòu)造替換字符串。作為示例,假設(shè)您正在回復(fù)一條消息。下例將在每一行前面加上短語(yǔ) "ralph said: ":

$ sed -e 's/.*/ralph said: &/' origmsg.txt
輸出如下:

ralph said: Hiya Jim, ralph said: ralph said:
I sure like this sed stuff! ralph said:
該例的替換字符串中使用了 '&' 字符,該字符告訴 sed 插入整個(gè)匹配的規(guī)則表達(dá)式。因此,可以將與 '.*' 匹配的任何內(nèi)容(行中的零或多個(gè)字符的最大組或整行)插入到替換字符串中的任何位置,甚至多次插入。這非常好,但 sed 甚至更強(qiáng)大。

那些極好的帶反斜杠的圓括號(hào)
's///' 命令甚至比 '&' 更好,它允許我們?cè)谝?guī)則表達(dá)式中定義區(qū)域,然后可以在替換字符串中引用這些特定區(qū)域。作為示例,假設(shè)有一個(gè)包含以下文本的文件:

foo bar oni eeny meeny miny larry curly moe jimmy the weasel
現(xiàn)在假設(shè)要編寫一個(gè) sed 腳本,該腳本將把 "eeny meeny miny" 替換成 "Victor eeny-meeny Von miny" 等等。要這樣做,首先要編寫一個(gè)由空格分隔并與三個(gè)字符串匹配的規(guī)則表達(dá)式。

'.* .* .*'
現(xiàn)在,將在其中每個(gè)感興趣的區(qū)域兩邊插入帶反斜杠的圓括號(hào)來(lái)定義區(qū)域:

'\(.*\) \(.*\) \(.*\)'
除了要定義三個(gè)可在替換字符串中引用的邏輯區(qū)域以外,該規(guī)則表達(dá)式的工作原理將與第一個(gè)規(guī)則表達(dá)式相同。下面是最終腳本:

$ sed -e 's/\(.*\) \(.*\) \(.*\)/Victor \1-\2 Von \3/' myfile.txt
如您所見,通過(guò)輸入 '\x'(其中,x 是從 1 開始的區(qū)域號(hào))來(lái)引用每個(gè)由圓括號(hào)定界的區(qū)域。輸入如下:

Victor foo-bar Von oni Victor eeny-meeny Von miny Victor larry-curly Von moe Victor jimmy-the Von weasel
隨著對(duì) sed 越來(lái)越熟悉,您可以花最小力氣來(lái)進(jìn)行相當(dāng)強(qiáng)大的文本處理。您可能想如何使用熟悉的腳本語(yǔ)言來(lái)處理這種問(wèn)題 -- 能用一行代碼輕易實(shí)現(xiàn)這樣的解決方案嗎?

組合使用
在開始創(chuàng)建更復(fù)雜的 sed 腳本時(shí),需要有輸入多個(gè)命令的能力。有幾種方法這樣做。首先,可以在命令之間使用分號(hào)。例如,以下命令系列使用 '=' 命令和 'p' 命令,'=' 命令告訴 sed 打印行號(hào),'p' 命令明確告訴 sed 打印該行(因?yàn)樘幱?'-n' 模式)。

$ sed -n -e '=;p' myfile.txt
無(wú)論什么時(shí)候指定了兩個(gè)或更多命令,都按順序?qū)⒚總(gè)命令應(yīng)用到文件的每一行。在上例中,首先將 '=' 命令應(yīng)用到第 1 行,然后應(yīng)用 'p' 命令。接著,sed 繼續(xù)處理第 2 行,并重復(fù)該過(guò)程。雖然分號(hào)很方便,但是在某些場(chǎng)合下,它不能正常工作。另一種替換方法是使用兩個(gè) -e 選項(xiàng)來(lái)指定兩個(gè)不同的命令:

$ sed -n -e '=' -e 'p' myfile.txt
然而,在使用更為復(fù)雜的附加和插入命令時(shí),甚至多個(gè) '-e' 選項(xiàng)也不能幫我們的忙。對(duì)于復(fù)雜的多行腳本,最好的方法是將命令放入一個(gè)單獨(dú)的文件中。然后,用 -f 選項(xiàng)引用該腳本文件:

$ sed -n -f mycommands.sed myfile.txt
這種方法雖然可能不太方便,但總是管用。

一個(gè)地址的多個(gè)命令
有時(shí),可能要指定應(yīng)用到一個(gè)地址的多個(gè)命令。這在執(zhí)行許多 's///' 以變換源文件中的字和語(yǔ)法時(shí)特別方便。要對(duì)一個(gè)地址執(zhí)行多個(gè)命令,可在文件中輸入 sed 命令,然后使用 '{ }' 字符將這些命令分組,如下所示:

1,20{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g }
上例將把三個(gè)替換命令應(yīng)用到第 1 行到第 20 行(包括這兩行)。還可以使用規(guī)則表達(dá)式地址或者二者的組合:

1,/^END/{         s/[Ll]inux/GNU\/Linux/g         s/samba/Samba/g         s/posix/POSIX/g         p }
該例將把 '{ }' 之間的所有命令應(yīng)用到從第 1 行開始,到以字母 "END" 開始的行結(jié)束(如果在源文件中沒(méi)發(fā)現(xiàn) "END",則到文件結(jié)束)的所有行。

附加、插入和更改行
既然在單獨(dú)的文件中編寫 sed 腳本,我們可以利用附加、插入和更改行命令。這些命令將在當(dāng)前行之后插入一行,在當(dāng)前行之前插入一行,或者替換模式空間中的當(dāng)前行。它們也可以用來(lái)將多行插入到輸出。插入行命令用法如下:

i\ This line will be inserted before each line
如果不為該命令指定地址,那么它將應(yīng)用到每一行,并產(chǎn)生如下的輸出:

This line will be inserted before each line line 1 here
This line will be inserted before each line line 2 here
This line will be inserted before each line line 3 here
This line will be inserted before each line line 4 here
如果要在當(dāng)前行之前插入多行,可以通過(guò)在前一行之后附加一個(gè)反斜杠來(lái)添加附加行,如下所示:

i\ insert this line\ and this one\ and this one\ and, uh, this one too.
附加命令的用法與之類似,但是它將把一行或多行插入到模式空間中的當(dāng)前行之后。其用法如下:

a\ insert this line after each line.  Thanks!
另一方面,“更改行”命令將實(shí)際替換模式空間中的當(dāng)前行,其用法如下:

c\ You're history, original line! Muhahaha!
因?yàn)楦郊印⒉迦牒透男忻钚枰诙嘈休斎,所以將把它們輸入到一個(gè)文本 sed 腳本中,然后通過(guò)使用 '-f' 選項(xiàng)告訴 sed 執(zhí)行它們。使用其它方法將命令傳遞給 sed 會(huì)出現(xiàn)問(wèn)題。
作者: 憂郁的葡萄    時(shí)間: 2007-03-28 14:17
標(biāo)題: 為啥會(huì)報(bào)這個(gè)錯(cuò)?
# cat test5
linux
Linux
samba
posix
# sed -e '{  s/[lL]inux/GNU\/linux/g s/samba/Samba/g s/posix/POSIX/g}' test5
sed: -e expression #1, char 28: unknown option to `s'
作者: zzzz991    時(shí)間: 2007-03-28 22:26
sed -e 's/[lL]inux/GNU\/linux/g;s/samba/Samba/g;s/posix/POSIX/g' test5
nux
GNU/linux
Samba
POSIX




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2