Sed and awk 筆記之 sed 篇:基礎(chǔ)命令

sed篇總共分成6章:(簡書版)

Sed&awk筆記之sed篇:簡單介紹

Sed&awk筆記之sed篇:模式空間與地址匹配

Sed&awk筆記之sed篇:sed基礎(chǔ)命令

Sed&awk筆記之sed篇:高級命令(一)

Sed&awk筆記之sed篇:高級命令(二)

Sed&awk筆記之sed篇:實戰(zhàn)

在開始之前蒲犬,首先回顧上一篇的重點內(nèi)容:地址匹配昆著。上一篇中介紹過,地址可以指定0個,1個或者2個嘹吨。地址的形式可以為斜杠分隔的正則表達式(例如/test/)藤滥,行號(例如3,5)或者特殊符號(例如$)暖混。如果沒有指定地址战坤,說明sed應用的編輯命令是全局的;如果是1個地址福稳,編輯命令只是應用到匹配的那一行涎拉;如果是一對地址,編輯命令則應用到該地址對匹配的行范圍的圆。關(guān)于地址匹配的內(nèi)容具體可以看Sed命令地址匹配問題總結(jié)鼓拧。

書中說,對于sed編輯命令的語法有兩種約定略板,分別是

[address]command? ? ? ? ? ? ? # 第一種

[line-address]command? ? ? ? ? # 第二種

第一種[address]是指可以為任意地址包括地址對毁枯,第二種[line-address]是指只能為單個地址。文中指出叮称,例如i(后方插入命令)种玛、a(前方追加命令)以及=(打印行號命令)等都屬于第二種命令,但是實際上我在ArchLinux上測試瓤檐,指定地址對也沒有報錯赂韵。不過為了兼容性,建議按作者所說的做挠蛉。

以下是要介紹的全部基礎(chǔ)命令:

名稱命令語法說明

替換s[address]s/pattern/replacement/flags替換匹配的內(nèi)容

刪除d[address]d刪除匹配的行

插入i[line-address]i\

text在匹配行的前方插入文本

追加a[line-address]a\

text在匹配行的后方插入文本

行替換c[address]c\

text將匹配的行替換成文本text

打印行p[address]p打印在模式空間中的行

打印行號=[address]=打印當前行行號

打印行l(wèi)[address]l打印在模式空間中的行祭示,同時顯示控制字符

轉(zhuǎn)換字符y[address]y/SET1/SET2/將SET1中出現(xiàn)的字符替換成SET2中對應位置的字符

讀取下一行n[address]n將下一行的內(nèi)容讀取到模式空間

讀文件r[line-address]r file將指定的文件讀取到匹配行之后

寫文件w[address]w file將匹配地址的所有行輸出到指定的文件中

退出q[line-address]q讀取到匹配的行之后即退出

替換命令: s

替換命令的語法是:

[address]s/pattern/replacement/flags

其中[address]是指地址,pattern是替換命令的匹配表達式谴古,replacement則是對應的替換內(nèi)容质涛,flags是指替換的標志位稠歉,它可以包含以下一個或者多個值:

n: 一個數(shù)字(取值范圍1-512),表明僅替換前n個被pattern匹配的內(nèi)容汇陆;

g: 表示全局替換怒炸,替換所有被pattern匹配的內(nèi)容;

p: 僅當行被pattern匹配時毡代,打印模式空間的內(nèi)容阅羹;

w file:僅當行被pattern匹配時,將模式空間的內(nèi)容輸出到文件file中教寂;

如果flags為空捏鱼,則默認替換第一次匹配:

$ echo"column1 column2 column3 column4"|sed's/ /;/'column1;column2 column3 column4

如果flags中包含g,則表示全局匹配:

$ echo"column1 column2 column3 column4"|sed's/ /;/g'column1;column2;column3;column4

如果flags中明確指定替換第n次的匹配酪耕,例如n=2:

$ echo"column1 column2 column3 column4"|sed's/ /;/2'column1 column2;column3 column4

當替換命令的pattern與地址部分是一樣的時候导梆,比如/regexp/s/regexp/replacement/可以省略替換命令中的pattern部分,這在單個編輯命令的情況下沒多大用處因妇,但是在組合命令的場景下還是能省不少功夫的问潭,例如下面是摘自文中的一個段落:

The substitute command is applied to the lines matching the address. If no

address is specified, it is applied to all lines that match the pattern, a

regular expression. If a regular expression is supplied as an address, and no

pattern is specified, the substitute command matches what is matched by the

address.? This can be useful when the substitute command is one of multiple

commands applied at the same address. For an example, see the section "Checking

Out Reference Pages" later in this chapter.

現(xiàn)在要在substitute command后面增加("s"),同時在被修改的行前面增加+號婚被,以下是使用的sed命令:

$ sed'/substitute command/{s//&("s")/;s/^/+ /}'paragraph.txt

這里我們用到了組合命令,并且地址匹配的部分和第一個替換命令的匹配部分是一樣的梳虽,所以后者我們省略了址芯,在replacement部分用到了&這個元字符,它代表之前匹配的內(nèi)容窜觉,這點我們在后面介紹谷炸。執(zhí)行后的結(jié)果為:

+ The substitute command("s") is applied to the lines matching the address. If no

address is specified, it is applied to all lines that match the pattern, a

regular expression. If a regular expression is supplied as an address, and no

+ pattern is specified, the substitute command("s") matches what is matched by the

+ address.? This can be useful when the substitute command("s") is one of multiple

commands applied at the same address. For an example, see the section "Checking

Out Reference Pages" later in this chapter.

替換命令的一個技巧是中間的分隔符是可以更改的(這個技巧我們在簡潔的Bash編程技巧續(xù)篇 - 5. 你知道sed的這個特性嗎?中也曾經(jīng)介紹過)禀挫,這個技巧在有些地方非常有用旬陡,比如路徑替換,下面是采用默認的分隔符和使用感嘆號作為分隔符的對比:

$ find/usr/local-maxdepth2-type d|sed's/\/usr\/local\/man/\/usr\/share\/man/'$ find/usr/local-maxdepth2-type d|sed's!/usr/local/man!/usr/share/man!'

替換命令中還有一個很重要的部分——replacement(替換內(nèi)容)语婴,即將匹配的部分替換成replacement描孟。在replacemnt部分中也有幾個特殊的元字符,它們分別是:

&: 被pattern匹配的內(nèi)容砰左;

\num: 被pattern匹配的第num個分組(正則表達式中的概念匿醒,\(..\)括起來的部分稱為分組;

\: 轉(zhuǎn)義符號缠导,用來轉(zhuǎn)義&廉羔,\, 回車等符號

&元字符我們已經(jīng)在上面的例子中介紹過,這里舉個例子介紹下\num的用法僻造。在Linux系統(tǒng)中憋他,默認都開了幾個tty可以讓你切換(ctrl+alt+1, ctrl+alt+2 ...)孩饼,例如CentOS 6.0+的系統(tǒng)默認是6個:

[root@localhost~]#grep-B1ACTIVE_CONSOLES/etc/sysconfig/init# What ttys should gettys be started on?ACTIVE_CONSOLES=/dev/tty[1-6]

可以通過修改上面的配置來減少開機啟動的時候創(chuàng)建的tty個數(shù),比如我們只想要2個:

[root@localhost~]#sed-r-i's!(ACTIVE_CONSOLES=/dev/tty\[1-)6]!\12]!'/etc/sysconfig/init

ACTIVE_CONSOLES=/dev/tty[1-2]

其中-i參數(shù)表示直接修改原文件竹挡,-r參數(shù)是指使用擴展的正則表達式(ERE)镀娶,擴展的正則表達式中分組的括號不需要用反斜杠轉(zhuǎn)義"(ACTIVE_CONSOLES=/dev/tty\[1-)",這里[是有特殊含義的(表示字符組)此迅,所以需要轉(zhuǎn)義汽畴。在替換的內(nèi)容中使用\1來引用這個匹配的分組內(nèi)容,1代表分組的編號耸序,表示第一個分組忍些。

刪除命令: d

刪除命令的語法是:

[address]d

刪除命令可以用于刪除多行內(nèi)容,例如1,3d會刪除1到3行坎怪。刪除命令會將模式空間中的內(nèi)容全部刪除罢坝,并且導致后續(xù)命令不會執(zhí)行并且讀入新行,因為當前模式空間的內(nèi)容已經(jīng)為空搅窿。我們可以試試:

$ sed'2,${d;=}'listJohnDaggett,341KingRoad,PlymouthMA

以上命令嘗試在刪除第2行到最后一行之后嘁酿,打印當前行號(=),但是事實上并沒有執(zhí)行該命令男应。

插入行/追加行/替換行命令: i/a/c

這三個命令的語法如下所示:

# Append 追加

[line-address]a\

text

# Insert 插入

line-address]i\

text

# Change 行替換

[address]c\

text

以上三個命令闹司,行替換命令(c)允許地址為多個地址,其余兩個都只允許單個地址(注:在ArchLinux上測試表明沐飘,追加和插入命令都允許多個地址游桩,sed版本為GNU sed version 4.2.1

追加命令是指在匹配的行后面插入文本text;相反地耐朴,插入命令是指匹配的行前面插入文本text借卧;最后,行替換命令會將匹配的行替換成文本text筛峭。文本text并沒有被添加到模式空間铐刘,而是直接輸出到屏幕,因此后續(xù)的命令也不會應用到添加的文本上影晓。注意镰吵,即使使用-n參數(shù)也無法抑制添加的文本的輸出。

我們用實際的例子來簡單介紹下這三個命令的用法俯艰,依然用最初的文本list:

$ cat listJohnDaggett,341KingRoad,PlymouthMAAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,SudburyMAHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,BostonMA

現(xiàn)在捡遍,我們要在第2行后面添加'------':

$ sed'2a\

--------------------------------------

'listJohnDaggett,341KingRoad,PlymouthMAAliceFord,22EastBroadway,RichmondVA--------------------------------------OrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,SudburyMAHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,BostonMA

或者可以在第3行之前插入:

$ sed'3i\

--------------------------------------

'listJohnDaggett,341KingRoad,PlymouthMAAliceFord,22EastBroadway,RichmondVA--------------------------------------OrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,SudburyMAHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,BostonMA

我們來測試下文本是否確實沒有添加到模式空間,因為模式空間中的內(nèi)容默認是會打印到屏幕的:

$ sed-n'2a\

--------------------------------------

'list--------------------------------------

通過-n參數(shù)來抑制輸出后發(fā)現(xiàn)插入的內(nèi)容依然被輸出竹握,所以可以判定插入的內(nèi)容沒有被添加到模式空間画株。

使用行替換命令將第2行到最后一行的內(nèi)容全部替換成'----':

$ sed'2,$c\

--------------------------------------

'listJohnDaggett,341KingRoad,PlymouthMA--------------------------------------

打印命令: p/l/=

這里純粹的打印命令應該是指p,但是因為后兩者(l和=)和p差不多,并且相對都比較簡單谓传,所以這里放到一起介紹蜈项。

這三個命令的語法是:

[address]p

[address]=

[address]l

p命令用于打印模式空間的內(nèi)容,例如打印list文件的第一行:

$ sed-n'1p'listJohnDaggett,341KingRoad,PlymouthMA

l命令類似p命令续挟,不過會顯示控制字符紧卒,這個命令和vim的list命令相似,例如:

$ echo"column1 column2 column3^M"|sed-n'l'column1\tcolumn2\tcolumn3\r$

=命令顯示當前行行號诗祸,例如:

$ sed'='list1JohnDaggett,341KingRoad,PlymouthMA2AliceFord,22EastBroadway,RichmondVA3OrvilleThomas,11345OakBridgeRoad,TulsaOK4TerryKalkas,402LansRoad,BeaverFallsPA5EricAdams,20PostRoad,SudburyMA6HubertSims,328ABrookRoad,RoanokeVA7AmyWilde,334BayshorePkwy,MountainViewCA8SalCarpenter,736thStreet,BostonMA

轉(zhuǎn)換命令: y

轉(zhuǎn)換命令的語法是:

[address]y/SET1/SET2/

它的作用是在匹配的行上跑芳,將SET1中出現(xiàn)的字符替換成SET2中對應位置的字符,例如1,3y/abc/xyz/會將1到3行中出現(xiàn)的a替換成x直颅,b替換成y博个,c替換成z。是不是覺得這個功能很熟悉功偿,其實這一點和tr命令是一樣的盆佣。可以通過y命令將小寫字符替換成大寫字符械荷,不過命令比較長:

$ echo"hello, world"|sed'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'HELLO,WORLD

使用tr命令來轉(zhuǎn)換成大寫:

$ echo"hello, world"|tr a-z A-Z

HELLO,WORLD

取下一行命令: n

取下一行命令的語法為:

[address]n

n命令為將下一行的內(nèi)容提前讀入共耍,并且將之前讀入的行(在模式空間中的行)輸出到屏幕,然后后續(xù)的命令會應用到新讀入的行上吨瞎。因此n命令也會同d命令一樣改變sed的控制流程痹兜。

書中給出了一個例子來介紹n的用法,假設(shè)有這么一個文本:

$ cat text.H1"On Egypt"Napoleon,pointing to thePyramids,said to his troops:"Soldiers, forty centuries have their eyes upon you."

現(xiàn)在要將.H1后面的空行刪除:

$ sed'/.H1/{n;/^$/d}'text.H1"On Egypt"Napoleon,pointing to thePyramids,said to his troops:"Soldiers, forty centuries have their eyes upon you."

讀寫文件命令: r/w

讀寫文件命令的語法是:

[line-address]r file

[address]w file

讀命令將指定的文件讀取到匹配行之后颤诀,并且輸出到屏幕佃蚜,這點類似追加命令(a)。我們以書中的例子來講解讀文件命令着绊。假設(shè)有一個文件text:

$ cat textForservice,contact any of the following companies:[Company-list]Thankyou.

同時我們有一個包含公司名稱列表的文件company.list:

$ cat company.listAlliedMayflowerUnited

現(xiàn)在我們要將company.list的內(nèi)容讀取到[Company-list]之后:

$ sed'/^\[Company-list]/r company.list'textForservice,contact any of the following companies:[Company-list]AlliedMayflowerUnitedThankyou.

更好的處理應當是用公司名稱命令替換[Company-list],因此我們還需要刪除[Company-list]這一行:

$ sed'/^\[Company-list]/r company.list;/^\[Company-list]/d;'textForservice,contact any of the following companies:[Company-list]Thankyou.

但是結(jié)果我們非但沒有刪除[Company-list]熟尉,而且company.list的內(nèi)容也不見了归露?這是怎么回事呢?

下面是我猜測的過程斤儿,讀文件的命令會將r空格后面的所有內(nèi)容都當成文件名剧包,即company.list;/^\[Company-list]/d;,然后讀取命令的時候發(fā)現(xiàn)該文件不存在往果,但是sed命令讀取不存在的文件是不會報錯的疆液。所以什么事都沒干成。

我們用-e選項將兩個命令分開就正常了:

$ sed-e'/^\[Company-list]/r company.list'-e'/^\[Company-list]/d;'textForservice,contact any of the following companies:AlliedMayflowerUnitedThankyou.

寫命令將匹配地址的所有行輸出到指定的文件中陕贮。假設(shè)有一個文件內(nèi)容如下堕油,前半部分是人名,后半部分是區(qū)域名稱:

$ cat textAdams,HenriettaNortheastBanks,FredaSouthDennis,JimMidwestGarvey,BillNortheastJeffries,JaneWestMadison,SylviaMidwestSommes,TomSouth

現(xiàn)在我們要將不同區(qū)域的人名字寫到不同的文件中:

$ sed'/Northeast$/w region.northeast

> /South$/w region.south

> /Midwest$/w region.midwest

> /West$/w region.west'textAdams,HenriettaNortheastBanks,FredaSouthDennis,JimMidwestGarvey,BillNortheastJeffries,JaneWestMadison,SylviaMidwestSommes,TomSouth

查看輸出的文件:

$ cat region.region.midwest? ? region.northeast? region.south? ? ? region.west

$ cat region.midwestDennis,JimMidwestMadison,SylviaMidwest

我們也可以試試將所有的w命令放到一起用分號分隔,發(fā)現(xiàn)會出下面的錯誤掉缺,它把w空格后面的部分當作文件名卜录,這樣就驗證了上面的猜測:

$ sed'/Northeast$/w region.northeast;/south$/w region.south;'text

sed:couldn't open file region.northeast;/south$/w region.south;: No such file or directory

退出命令: q

退出命令的語法是

[line-address]q

當sed讀取到匹配的行之后即退出,不會再讀入新的行眶明,并且將當前模式空間的內(nèi)容輸出到屏幕艰毒。例如打印前3行內(nèi)容:

$ sed'3q'listJohnDaggett,341KingRoad,PlymouthMAAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOK

打印前3行也可以用p命令:

$ sed-n'3p'listJohnDaggett,341KingRoad,PlymouthMAAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOK

但是對于大文件來說,前者比后者效率更高搜囱,因為前者讀取到第N行之后就退出了丑瞧。后者雖然打印了前N行,但是后續(xù)的行還是要繼續(xù)讀入蜀肘,只不會不作處理绊汹。

到此為止,sed基礎(chǔ)命令的部分就介紹完了幌缝。下面一篇的內(nèi)容會在最近幾天更新上來灸促,主要會介紹sed高級命令。不過一般情況下涵卵,會使用基礎(chǔ)命令已經(jīng)差不多了浴栽,高級命令不一定需要去了解。

下面是我整理的一份思維導圖(附.xmind文件下載地址):

轉(zhuǎn)自:團子的小窩, 本文固定鏈接:Sed and awk 筆記之 sed 篇:基礎(chǔ)命令

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轿偎,一起剝皮案震驚了整個濱河市典鸡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坏晦,老刑警劉巖萝玷,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昆婿,居然都是意外死亡球碉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門仓蛆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睁冬,“玉大人,你說我怎么就攤上這事看疙《共Γ” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵能庆,是天一觀的道長施禾。 經(jīng)常有香客問我,道長搁胆,這世上最難降的妖魔是什么弥搞? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任邮绿,我火速辦了婚禮,結(jié)果婚禮上拓巧,老公的妹妹穿的比我還像新娘斯碌。我一直安慰自己,他們只是感情好肛度,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布傻唾。 她就那樣靜靜地躺著,像睡著了一般承耿。 火紅的嫁衣襯著肌膚如雪冠骄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天加袋,我揣著相機與錄音凛辣,去河邊找鬼。 笑死职烧,一個胖子當著我的面吹牛扁誓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚀之,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蝗敢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了足删?” 一聲冷哼從身側(cè)響起寿谴,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎失受,沒想到半個月后讶泰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拂到,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年痪署,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兄旬。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡惠桃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辖试,到底是詐尸還是另有隱情,我是刑警寧澤劈狐,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布罐孝,位于F島的核電站,受9級特大地震影響肥缔,放射性物質(zhì)發(fā)生泄漏莲兢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望改艇。 院中可真熱鬧收班,春花似錦、人聲如沸谒兄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽承疲。三九已至邻耕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間燕鸽,已是汗流浹背兄世。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啊研,地道東北人御滩。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像党远,于是被迫代替她去往敵國和親削解。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容