国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
- SCO UNIX - Unix Shell 實(shí)例精解 - ChinaUnix.net
第一章 關(guān)于UNIX Shell的介紹

1. 定義
shell 是一種特殊的程序,被用作用戶與內(nèi)核(kernel)的UNIX操作系統(tǒng)核心
通訊。常見的shell有C shell、B shell 和 Korn shell(B shell的超集)。


2. shell 主要功能
.. 解釋交互運(yùn)行時(shí),在命令行提示下敲入的命令
.. 制訂用戶環(huán)境,通常在shell初始化文件中作這種工作。例如:設(shè)置終
端鍵及窗口特征;設(shè)置搜索路徑、權(quán)限、提示等
.. shell 可以用作解釋編程語(yǔ)言。Shell程序也叫命令表,由再文件中列出
的命令組成。


3. 主要shell命令:
who mv rm wc ls cat date at
lpr rsh more awk pwd bc vi finger w
pg find cc cp dd grep ksh sh
ps sed cal lp



第2章 UNIX工具箱

1.正則表達(dá)式
一個(gè)正則表達(dá)式就是用來(lái)在一次搜索中匹配相同字符的一個(gè)字符模式。在大
多數(shù)程序中,把一個(gè)正則表達(dá)式封裝在正斜杠(/)里。


2.正則表達(dá)式元字符


元字符

功能

實(shí)例

解釋

^

行開頭定位

/^love/

與所有l(wèi)ove開頭的行匹配

$

行末尾定位

/love$/

與所有l(wèi)ove結(jié)尾的行匹配

.

匹配單個(gè)字符

/l..e/

與包含一個(gè)l,后跟兩個(gè)字符,然后跟一個(gè)e的行相匹配 *

跟前驅(qū)的0個(gè)或多
個(gè)字符相匹配

/ *love/

跟0個(gè)或多個(gè)空格后面的
love模式的行相匹配

[]

與其中的一個(gè)相匹


/[Ll]ove/

與包含love或者Love的行
匹配

[x-z]

與集中一個(gè)范圍內(nèi)
的一個(gè)字符相匹配

/[A-Z]ove/

與后面跟ove的從A到Z的
字相匹配

[^]

與不在集里的字符
匹配

/[^A-Z]ove/

不包括A到Z,后面跟ove
的字相匹配

\

給一個(gè)元字符轉(zhuǎn)移

/love\./

匹配行包括love,跟一個(gè)句
點(diǎn)

許多用RE元字符的UNIX程序支持的附加元字符(vi 和 grep支持)

\<

詞開頭定位

/\<love/

匹配行包含用love開頭的


\>;

詞結(jié)尾定位

/love\>;/

匹配行包含love結(jié)尾的詞

\(..\)

標(biāo)志與以后用的字
符相匹配

/(love\)able\ler/

Able可達(dá)9個(gè)標(biāo)志,模式最
左邊用第一個(gè)標(biāo)志開始。例
如,模式love保存作標(biāo)志
l,以后引用作\l;在這個(gè)例
子中,搜索模式包括后面跟
lover的lovable

x\{m\}

x\{m,\}

x\{m,n\}

字符x重復(fù)m次

至少m次

m到n次

O\{5,10\}

如果行包含5—10個(gè)連續(xù)的
o則匹配



表(2.1)

3.舉例
查找文件中的含有l(wèi)ove的詞:

% vi picnic

I had a lovely time on our little picnic. Lovers were all around
us, oh love

:/love/


4.組合正則表達(dá)式元字符
文件內(nèi)容:(數(shù)字是行號(hào),豎線標(biāo)明行的左右邊界,不屬于文件內(nèi)容。這個(gè)文





件我寫在shell/exam/exam_2.9中)


1 |Christian Scott lives here and will put on a Christmas party.|
2 |There are around 30 to 35 people invited.|
3 |They are: |
4 | Tom|
5 |Dan|
6 | Rhonda Savage|
7 |Nicky and Kimerly.|
8 |Steve, Suzanne, Ginger and Larry.|


組合舉例:
.. /^[A-Z]..$/
搜索行以A至Z的一個(gè)字母開頭,然后跟兩個(gè)任意字母,然后跟一
個(gè)換行符的行。將找到第5行。


.. /^[A-Z][a-z]*3[0-5]/
搜索以一個(gè)大寫字母開頭,后跟0個(gè)或多個(gè)小寫字母,再跟數(shù)字3,
再跟0—5之間的一個(gè)數(shù)字。


.. *[A-Z][a-z][a-z]$/
搜索以0個(gè)或多個(gè)空格開頭,跟一個(gè)大寫字母,兩個(gè)小寫字母和一
個(gè)換車符。將找到第4行的TOM(整行匹配)和第5行。注意,*前
面有一個(gè)空格。


.. /^[A-Za-z]*[^,][A-Za-z]*$/
將查找以0個(gè)或多個(gè)大寫或小寫字母開頭,不跟逗號(hào),然后跟0個(gè)
或多個(gè)大寫或小寫字母,然后跟一個(gè)換車符。將找到第5行。書中
解釋有誤。




5.更多的正則表達(dá)式元字符
這里討論的元字符不一定可以移植到所有的正則表達(dá)式中,但一般可以用在
vi、sed和grep中。

% vi textfile

Patty won fourth place in the 50 yard dash square and fair.

Occurences like this are rare.

Haha, what you want is just fourth.

~

~

:/\<fourth\>;/

將查找詞fourth







第3章 grep家族

1.grep的含義是“全局搜索正則表達(dá)式(RE)并打印該行”
2.grep支持的正則表達(dá)式
與在文件中搜索基本一樣??梢詤⒖急?.1。


3.grep 的選項(xiàng)


選項(xiàng)

功能

-b

在各行之前放置它發(fā)現(xiàn)的塊號(hào)。有時(shí)在根據(jù)上下文定位磁盤字塊時(shí)有用

-c

顯示匹配行數(shù)而不是內(nèi)容

-h

不顯示文件名

-I

在座比較時(shí)忽略字母大小寫

-n

文件中每行之前給出它的相關(guān)行號(hào)

-s

無(wú)聲操作。即除了錯(cuò)誤消息外不做任何顯示。用于檢查退出狀態(tài)

-v

把搜索翻轉(zhuǎn)為只顯示不匹配的行

-w

把表達(dá)式當(dāng)作一個(gè)次來(lái)搜索,相當(dāng)于用\<和\>;括起來(lái)







表3.1

4.grep命令的退出狀態(tài)
如果grep操作成功,則狀態(tài)是0,如果模式?jīng)]找到,狀態(tài)是1,如果文件沒(méi)
找到,狀態(tài)是2。如果操作被取消,則狀態(tài)是130。查看狀態(tài)的方法:在csh
中用echo $status。在sh和ksh中用echo $? 。例如

$ echo $?

0


5.帶正則表達(dá)式的grep舉例:
用于這些例子的文件叫datafile,位于chap03目錄。內(nèi)容如下:

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9

central CT Ann Stephens 5.7 .94 5 13


1) grep NW datafile
解釋:打印datafile中包含NW的行


2) grep NW d*
解釋:打印所有以d開頭的文件中含有NW的文件。


3) grep ‘^n‘ datafile
解釋:打印文件datafile中所有以字母n開頭的行


4) grep TB Savage datafile
解釋:在Savage和datafile文件中查找有TB的行


5) grep ‘TB Savage‘ datafile
解釋:在datafile文件中查找含有TB Savage的行并打印。這個(gè)例子在







書中有誤。


6) grep ‘^[we]‘ datafile
打印datafile中以w或者e開頭的行


7) grep ‘ss* ‘ datafile
northwest NW Charles Main 3.0 .98 3 34

southwest SW Lewis Dalsass 2.7 .8 2 18

解釋:打印所有包含一個(gè)s并跟0個(gè)或者多個(gè)s,然后跟一個(gè)空格的行




6.用管道的grep
grep 可以從管道得到輸入。

% ls –l

drwxr-xr-x 6 oracle dba 512 4月 3 21:49 chap10

drwxr-xr-x 2 oracle dba 512 4月 10 22:23 exam

-rwxr--r-- 1 oracle dba 1842 4月 3 21:51 readme.txt

-rwxr--r-- 1 oracle dba 1801 4月 3 21:51 unix_readme.txt

% ls –l | grep ‘^d‘

drwxr-xr-x 6 oracle dba 512 4月 3 21:49 chap10

drwxr-xr-x 2 oracle dba 512 4月 10 22:23 exam

% ls -l |grep ‘^[^d]‘

-rwxr--r-- 1 oracle dba 1842 4月 3 21:51 readme.txt

-rwxr--r-- 1 oracle dba 1801 4月 3 21:51 unix_readme.txt


7.帶選項(xiàng)的grep舉例:
grep –c ‘west’ datafile

3

解釋計(jì)算datafile中含有west的總數(shù)。


8.egrep (擴(kuò)展的grep)
egrep可以使用額外的正則表達(dá)式,如下表。




元字符

功能

例子

解釋

+

匹配一個(gè)或多個(gè)前驅(qū)字符

‘[a-z]+ove‘

匹配一個(gè)或多個(gè)小寫
字母,后跟ove



匹配0個(gè)或者1個(gè)前驅(qū)字


‘lo?ve‘

將找到love或love

a|b

匹配a或者b

‘love|hate‘

與love或hate匹配

()

組字符

‘lov(ely|able)

與lovely或lovable
匹配



表3.2

9.egrep 舉例:
egrep ‘2\.?[0-9]‘ datafile

解釋:打印所有這樣的行:它包含一個(gè)2,后跟0個(gè)或者一個(gè)句號(hào),然后跟
一個(gè)數(shù)字。


10. fgrep
fgrep 把所有的元字符都當(dāng)作字符本身,只代表自己。


11. UNIX 工具試驗(yàn)參考答案(內(nèi)容參考datebook)
.. 打印包含San的行
grep ‘San‘ datebook







.. 打印所有以J開頭的人名所在的行
grep ‘^J‘ datebook


.. 打印以700結(jié)尾的行


grep ‘700$‘ datebook
.. 打印所有不包含834的行


grep -v ‘834‘ datebook
.. 打印出生在12月(December)的行


grep ‘/12‘ datebook
.. 打印工資是6位數(shù)的行,并給出行號(hào)


grep -n ‘[0-9]\{6,\}$‘ datebook



第4章 流編輯器(sed)


1. sed 命令簡(jiǎn)介




sed 是流線型、非交互式編輯器。它允許你執(zhí)行與vi 和ex編輯器里一樣的
編輯任務(wù)。Sed 程序不是與編輯器交互式工作的,而是讓你在命令行里敲入編輯
的命令,給文件命名,然后在屏幕上查看命令輸出結(jié)果。

2. sed 如何工作


sed 編輯器按一次處理一行的方式來(lái)處理文件,并把輸出送到屏幕上。

3. sed 可以用尋址的方式來(lái)決定想要編輯哪一行。
4. sed 命令和選項(xiàng)


命令

功能

a\

在當(dāng)前行上添加一個(gè)文本行或者多個(gè)文本行

c\

用新聞本改變(取代)當(dāng)前行里的文本

d

刪除行

i\

在當(dāng)前行之前插入文本

h

把模式空間內(nèi)容復(fù)制到一個(gè)固定緩存

H

把模式空間內(nèi)容添加到一個(gè)固定緩存

g

得到固定緩存里所有的稟復(fù)制到模式緩存,重寫其內(nèi)容

G

得到固定緩存的內(nèi)容并復(fù)制到模式緩存,添加到里面

I

列出不打印的字符

p

打印行

n

讀下一輸入行,并開始用下一個(gè)命令處理?yè)Q行符,而不是用第一個(gè)
命令

q

結(jié)束或退出sed

r

從一個(gè)文件讀如行

!

把命令應(yīng)用到除了選出的行以外的其他所有行

s

把一個(gè)字串替換成另一個(gè)

替換標(biāo)志

g

在一行上進(jìn)行全局替換

p

打印行

w

把行寫到一個(gè)文件中

x

用模式空間的內(nèi)容交換固定緩存的內(nèi)容

y

把一個(gè)字符轉(zhuǎn)換成另一個(gè)(不能和整則表達(dá)式元字符一起使用)





5. sed 元字符


基本上,grep和vi使用的元字符都可以用在sed中。具體可參照第二章。

下表列出了一些特別的sed 元字符:

元字符

功能

例子

解釋

&

保存搜索串以便可
以記在替換串里

s/love/**&**/

&號(hào)代表搜索串。串love將被星
號(hào)包圍的自身所替代;即love
變成**love**





6. sed 的實(shí)例(使用datafile)



1>; 打?。簆命令


sed ‘/north/p‘ datafile
默認(rèn)輸出所有行,找到north的行重復(fù)打印

sed –n ‘/north/p‘ datafile

禁止默認(rèn)輸出,只打印找到north的行


2>; 刪除:d命令
sed ‘3d‘ datafile

刪除第三行,其余行輸出到屏幕

sed ‘3,$d‘ datafile

從第3行到最后一行都刪除,將剩余部分輸出到屏幕

sed ‘/north/d‘ datafile

將含有north的行刪除,其余輸出到屏幕


3>; 替換:s命令


sed ‘s/west/north/g‘ datafile
解釋:找到datafile中的所有west并替換成north,將替換后的內(nèi)容輸
出到屏幕。

sed ‘s/[0-9][0-9]$/&.5/‘ datafile

解釋:在替代串里的&字符代表在搜索串中真正找到的。每個(gè)以兩個(gè)數(shù)字
結(jié)尾的行都被它自己取代,且要在后面加上.5

sed -n ‘s/Hemenway/Jones/gp‘ datafile

解釋:所有的Hemenway所在的位置都用Jones來(lái)取代,而且只有改變的
行被打印。-n與p命令選項(xiàng)相結(jié)合來(lái)禁止默認(rèn)輸出。g代表全局替換

sed -n ‘s/\(Mar\)got/\1ianne/p‘ datafile

解釋:模式Mar被封裝在括弧里且在一個(gè)專用寄存器里存為標(biāo)記1。在替
換串里它將被引用做\1。然后用Marianne替代Margot。

sed ‘s#3#88#g‘ datafile

s命令后面的字符是搜索串和替換串之間的分界符。默認(rèn)的分界符是一個(gè)
正斜杠,但也可以改變(只有使用s命令時(shí))。無(wú)論s命令后面跟什么字
符,它都是新的串分界符。當(dāng)搜索包含一個(gè)正斜杠的模式,如路徑或生
日時(shí),這種技巧可能有用


4>; 被選中的行的范圍:逗號(hào)


sed -n ‘/west/,/east/p‘ datafile
打印在west和east之間的模式范圍內(nèi)所有行。如果west出現(xiàn)在east
之后,則打印從west到下一個(gè)east或者到文件末尾的行,無(wú)論哪種情
況先出現(xiàn)都可以。

sed ‘/west/,/east/s/$/**VACA**/‘ datafile

解釋:對(duì)于在模式west到east范圍內(nèi)的行,行末尾將用**VACA**來(lái)取代。


5>; 多次編輯 -e 選項(xiàng)


sed -e ‘1,3d‘ -e ‘s/Hemenway/Jones/‘ datafile
-e選項(xiàng)允許多次編輯。不同的編輯順序可能導(dǎo)致不同的結(jié)果。例如,如
果兩個(gè)命令都執(zhí)行了替換,第一次替換可能影響第二次替換。


6>; 從文件中讀?。簉命令


sed ‘/Suan/r newfile‘ datafile
解釋:r命令從newfile中讀取內(nèi)容,將內(nèi)容輸出到Suan的后面。如果





datafile中Suan出現(xiàn)的次數(shù)不只一次,則分別放到Suan的后面。


7>; 寫入文件:w命令


sed -n ‘/north/w newfile‘ datafile
解釋:w命令把指定的行寫入到一個(gè)文件。本例中所有的包含north的行
寫入到newfile中。等同于sed -n ‘/north/p‘ datafile >;newfile


8>; 添加:a命令
$ sed ‘/north/a\

>; ---->;THE NORTH SALES DISTRICT HAS MOVED<-----‘ datafile

northwest NW Charles Main 3.0 .98 3 34

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

north NO Margot Weber 4.5 .89 5 9

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

central CT Ann Stephens 5.7 .94 5 13

解釋:紅顏色的內(nèi)容是要輸入的內(nèi)容。a\命令后面跟要添加的內(nèi)容。奇怪的是a\后
面必須另起一行,在輸入要添加的內(nèi)容,否則會(huì)提示命令錯(cuò)亂,真是搞不懂。


9>; 插入:i命令
$ sed ‘/north/i\

>; ---->;THE NORTH SALES DISTRICT HAS MOVED<-----‘ datafile

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

northeast NE AM Main Jr. 5.1 .94 3 13

---->;THE NORTH SALES DISTRICT HAS MOVED<-----

north NO Margot Weber 4.5 .89 5 9

central CT Ann Stephens 5.7 .94 5 13

解釋:在符合模式的行前面插入內(nèi)容。其余和a\命令相同。


10>;下一個(gè):n命令
$ sed ‘/eastern/{n;s/AM/Archie/;}‘ datafile

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15







southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE Archie Main Jr. 5.1 .94 3 13

……




解釋:如果在某一行里模式eastern被匹配,n命令使sed區(qū)的下一行,
用該行帶換模式空間,用Archie替換AM,打印并繼續(xù)。
11>;變換:y 命令


sed ‘1,3y/abcdefghijklmnopqrst/ABCDEFGHIJKLMNOPQRST/‘ datafile
解釋將對(duì)應(yīng)字母進(jìn)行轉(zhuǎn)換。


12>;退出:q 命令


sed ‘5q‘ datafile
解釋:在打印了5行之后,用q命令退出sed程序。


13>;保存和取得:h和G命令
$ sed -e ‘/southeast/h‘ -e ‘$G‘ datafile

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9

central CT Ann Stephens 5.7 .94 5 13

southeast SE Patricia Hemenway 4.0 .7 4 17

解釋:當(dāng)sed 處理文件時(shí),每行都存在模式空間(pattern space)的臨時(shí)緩存中。
除非行被禁止打印或刪除,否則行將在處理完后被打印到屏幕,然后請(qǐng)模式空間并把
下一輸入行保存在那里等待處理。在這個(gè)例子中,在找到模式之后,把它放在模式
空間里,而且h命令復(fù)制它并把它存到另一個(gè)叫做保存緩存(holding buffer)中。
第二個(gè)sed指令里,當(dāng)讀入最后一行($)時(shí),G命令告訴sed從包存緩存中取得該行
并放回模式空間緩存,添加到當(dāng)前存在那里的行中。本例子就是最后一行。

$ sed -e ‘/WE/{h;d;}‘ -e ‘/CT/G‘ datafile

northwest NW Charles Main 3.0 .98 3 34

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

north NO Margot Weber 4.5 .89 5 9

central CT Ann Stephens 5.7 .94 5 13

western WE Sharon Gray 5.3 .97 5 23

解釋:第一個(gè)命令h將找到了WE的行放到保存緩存中,然后刪除該行;第二個(gè)命令
/CT/G就是在找到了CT的行的后面加入保存緩存的內(nèi)容。


14>;G和g的區(qū)別
G命令在符合的條件行后面添加保存緩存中的內(nèi)容;g命令用保存緩存中







的內(nèi)容覆蓋符合條件的行。


15>;sed 命令的花括號(hào){}的作用
花括號(hào){}中可以放入多個(gè)命令,每個(gè)命令后面要用分號(hào);。


16>;保存和交換:h 和 x命令。
$ sed -e ‘/Patricia/h‘ -e ‘/Margot/x‘ datafile

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

southeast SE Patricia Hemenway 4.0 .7 4 17

central CT Ann Stephens 5.7 .94 5 13

解釋:x命令將找到的行用保存緩存中的內(nèi)容替換。




7. 用sed來(lái)編寫命令表
sed 命令表(script)是文件里的一個(gè)sed命令列表。用-f選項(xiàng)來(lái)引用一
個(gè)命令表文件。編輯sed命令表有特殊要求:命令末尾不能有任何為歲的空
白符或者文本。如果命令不是自成一行,就必須用分號(hào)結(jié)束。在源代碼chap4
目錄下有兩個(gè)編輯好的命令表文件(sedding1和sedding2)可以參考。下面是
使用sed命令表的例子。

$ sed -f sedding1 datafile

EMPLOYEE DATABASE

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

northwest NW Charles Main 3.0 .98 3 34

western WE Sharon Gray 5.3 .97 5 23

southwest SW Lewis Dalsass 2.7 .8 2 18

Lewis is the TOP Salesperson for April!!

Lewis is moving to the southern district next month.

CONGRATULATIONS!

southern SO Suan Chin 5.1 .95 4 15

southeast SE Patricia Hemenway 4.0 .7 4 17

eastern EA TB Savage 4.4 .84 5 20

northeast NE AM Main Jr. 5.1 .94 3 13

*******************

MARGOT HAS RETIRED

*******************


8. Sed練習(xí)參考答案


練習(xí)內(nèi)容參考databook文件

1〉 把Jon改成Jonathan


sed ‘s/Jon/Jonathan/‘ datebook

2〉 刪除頭3行


sed ‘1,3d‘ datebook

3〉 打印5—10行



sed -n ‘5,10p‘ datebook

4〉 刪除包含Lane的行


sed ‘/Lane/d‘ datebook

5〉 打印所有生日是在Noverber到December之間的行


sed -n ‘/:1[12]\//p‘ datebook

6〉 把三個(gè)星添加到以Fred開頭的行尾


sed ‘/^Fred/s/$/***/‘ datebook

7〉 用JOSE HAS RETIRED取代包含Jose的行


sed ‘s/^Jose[0-9]*[a-z]*[A-Z]* *.*$/JOSE HAS LEFT/‘ datebook

8〉 把Popeye的生日改成11/14/46


sed ‘/Popeye/s/:[0-9]*[0-9]*\/[0-9]*[0-9]*\/[0-9]*[0-9]*/:11\/14\/46/‘ datebook

9〉 刪除所有空白行


sed ‘/^$/d‘ datebook

10〉 寫一個(gè)sed命令表,將:
a. 在第1行之前插入標(biāo)題PERSONNEL FILE
b. 刪除以500結(jié)尾的工資
c. 打印文件內(nèi)容,把姓和名顛倒
d. 在文件末尾添加THE END


答案放在chap04/a10文件中,內(nèi)容如下:
# My first sed script by Wangzhh.

1i\

PERSONNEL FILE

/500/d

s/\([A-Z][a-z]*\) \([A-Z][a-z]*\):/\2 \1:/

$a\

THE END





第5章 awk 實(shí)用程序:awk作為一種UNIX工具

1. awk 簡(jiǎn)介
awk 是用來(lái)操作數(shù)據(jù)和產(chǎn)生報(bào)表的一種編程語(yǔ)言。數(shù)據(jù)可能來(lái)自標(biāo)準(zhǔn)輸入、
一個(gè)或者多個(gè)文件或者是一個(gè)進(jìn)程的輸出。awk 可以用在命令行里用于簡(jiǎn)單
操作,或者可以為了較大的應(yīng)用而寫到程序中。常見的awk命令有awk、nawk
等。awk從第1行到最后一行逐行掃描文件(或輸入),并執(zhí)行選定的操作(封
裝在花括號(hào)里)。本文章所有的例子使用的文件未經(jīng)說(shuō)明都在chap05目錄下。


2. awk的格式
awk程序由awk命令,封裝在引號(hào)里(或在一個(gè)文件里)的程序指令,和輸
入文件組成。如果沒(méi)有指定一個(gè)輸入文件,則輸入來(lái)自標(biāo)準(zhǔn)輸入(stin)鍵盤。

employees文件中的內(nèi)容:

$ cat employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500


1〉從文件輸入


$ awk ‘/Mary/‘ employees
解釋:打印employees文件中含有Mary的行

$ awk ‘{print $1}‘ employees

Tom

Mary

Sally

Billy

解釋:打印文件employees中的第一個(gè)域。域的分隔符是空格。

nawk ‘/Sally/{print $1,$2}‘ employees

解釋:只有找到了Sally的行才打印第一個(gè)域和第二個(gè)域。


2〉管道輸入
$ df -k|awk ‘$4>;1024000‘

解釋:報(bào)告剩余空間大于1024000k的盤。




3. 格式化輸出
1〉print函數(shù)
例子1:

$ date

2005年04月30日 星期六 19時(shí)29分25秒 CST

$ date|awk ‘{print "Date:" $1 "\nTime:" $3}‘

Date:2005年04月30日

Time:19時(shí)34分24秒

注意,用date命令查看時(shí)間格式。不同的語(yǔ)言可能格式也不一樣,因此
awk也要隨之而變。\n是轉(zhuǎn)義序列,表示換行符。常見轉(zhuǎn)義序列如下表:














轉(zhuǎn)義序列

含義

\b

退格

\f

換頁(yè)

\n

換行

\r

回車

\t

跳格

\047

八進(jìn)制值47,一個(gè)單引號(hào)

\c

C代表任意其它字符,例如\‘‘



表5.1 轉(zhuǎn)義序列

例子2:

$ nawk ‘/Sally/{print "\t\tHave a nice day, "$1,$2 "\!"}‘ employees

Have a nice day, Sally Chang!

解釋:如果包含模式Sally,則print函數(shù)打印兩個(gè)跳格,串Have a nice
day,第一個(gè)域和第二個(gè)域,然后跟嘆號(hào)。

OFMT變量:當(dāng)打印數(shù)字時(shí),如果使用print函數(shù),想控制精度時(shí),可以
用OFMT變量。默認(rèn)設(shè)置是“%.6g”,也就是打印精度到小數(shù)點(diǎn)后6位。下
面的例子可以改變精度。

$ nawk ‘BEGIN{OFMT="%.2f"; print 1.23456789,12E-2}‘

1.23 0.12

2〉printf函數(shù)
printf函數(shù)提供了強(qiáng)大的格式化輸出功能,如果對(duì)c比較熟悉,就不會(huì)
感覺(jué)太陌生。




轉(zhuǎn)換字符

定義

c

字符

s



d

十進(jìn)制數(shù)

ld

長(zhǎng)十進(jìn)制數(shù)

u

無(wú)符號(hào)十進(jìn)制數(shù)

lu

無(wú)符號(hào)長(zhǎng)十進(jìn)制數(shù)

x

十六進(jìn)制數(shù)

lx

長(zhǎng)十六進(jìn)制數(shù)

o

八進(jìn)制數(shù)

lo

長(zhǎng)八進(jìn)制數(shù)

e

以科學(xué)技術(shù)發(fā)記的符點(diǎn)數(shù)

f

浮點(diǎn)數(shù)

g

從e或f轉(zhuǎn)換中選擇一種占用空間最少的記符點(diǎn)數(shù)



表5.2 printf的轉(zhuǎn)換字符




字符

定義

-

左對(duì)齊修飾符

#

整數(shù)在用八進(jìn)制顯示前面有個(gè)0;整數(shù)在用十六進(jìn)制顯示時(shí)
前面有個(gè)0x

+

對(duì)于用d、e、f和g的轉(zhuǎn)換,帶一個(gè)數(shù)字符號(hào)+或-顯示整數(shù)

0

顯示的值用0補(bǔ)而不是用空格



表5.3修飾符



格式符

功能

假設(shè)x=’A’ y=15 z=2.3 $1=Bob Smith

%c

打印一個(gè)單ASCII字符

$ printf "The character is %c\n" $x

The character is A

%d

打印一個(gè)十進(jìn)制數(shù)

$ printf "The boy is %d years old\n" $y

The boy is 15 years old

%e

打印用科學(xué)計(jì)數(shù)法記的一個(gè)數(shù)

$ printf "z is %e\n" $z

z is 2.300000e+00

%f

打印一個(gè)符點(diǎn)數(shù)

$ printf "z is %f\n" $z

z is 2.300000

%o

打印一個(gè)數(shù)的八進(jìn)制值

$ printf "y is %o\n" $y

y is 17

%s

打印一個(gè)字符串

$ printf "The name of the culprit is %s\n" $1

The name of the culprit is Bob Smith

%x

打印一個(gè)數(shù)的十六進(jìn)制值

$ printf "y is %x\n" $y

y is f



表5.4 printf格式說(shuō)明符

例子:

$ echo UNIX |awk ‘{printf "|%-15s|\n",$1}‘

|UNIX |

解釋:echo命令輸出從管道中送給awk。格式說(shuō)明符說(shuō)明將會(huì)打印一個(gè)
占15個(gè)空格,左對(duì)齊,封裝在豎杠里而且有換行的串。

$ awk ‘{printf "The name is %-15s ID is %8d\n",$1,$3}‘ employees

The name is Tom ID is 4424

The name is Mary ID is 5346

The name is Sally ID is 1654

The name is Billy ID is 1683

4. 在一個(gè)文件里的awk命令



如果awk命令放在文件里,就使用-f選項(xiàng)和awk文件名結(jié)合使用。處理過(guò)程:
把一條記錄讀到awk的緩存里而且對(duì)該記錄測(cè)試并執(zhí)行awk文件里的每個(gè)命
令。在awk完成對(duì)第一條記錄的操作后,刪除該記錄并把下一條記錄讀入緩
存,依此類推。如果操作不受模式控制,則默認(rèn)行為是打印整個(gè)記錄。

例子:

$ cat employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

$ cat awkfile

/^Mary/{print "Hello Mary!"}

{print $1, $2, $3}

$ nawk -f awkfile employees

Tom Jones 4424

Hello Mary!

Mary Adams 5346

Sally Chang 1654

Billy Black 1683


5. 記錄和域
1〉記錄:awk不把輸入數(shù)據(jù)看作一個(gè)無(wú)窮的字符串,而是把它看作一種格式
或結(jié)構(gòu)。默認(rèn)情況下把每行叫做一個(gè)記錄(record),并以一個(gè)換行符終
止。輸入和輸出的記錄分隔符默認(rèn)是回車符,保存在內(nèi)置awk變量ORS
和RS中。ORS和RS可以改變,但是方式有限。
例子:

$ nawk ‘{print $0}‘ employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

解釋:變量$0保存當(dāng)前記錄,這條命令相當(dāng)于nawk ‘{print}‘ employees

例子:

$ awk ‘{print NR,$0}‘ employees

1 Tom Jones 4424 5/12/66 543354

2 Mary Adams 5346 11/4/63 28765

3 Sally Chang 1654 7/22/54 650000

4 Billy Black 1683 9/23/44 336500

解釋:NR代表行號(hào)。


2〉域
類似表中的字段,是指記錄中的一個(gè)詞條。默認(rèn)域分隔符是空白區(qū)域,
也就是空格或制表符(TAB)。Awk中用NF來(lái)記錄每條記錄的域數(shù)量。


3〉域分隔符
輸入域分隔符:awk的內(nèi)置變量FS保存輸入域分隔符的值。當(dāng)時(shí)用FS
的默認(rèn)值時(shí),awk用空格或制表符分隔域,刪除前導(dǎo)空白區(qū)和制表符。FS







可以改變,可以在BEGIN語(yǔ)句中改變,也可以在命令中改變。要想在命
令中改變需要用-F選項(xiàng)。

舉例:

$ cat employees2

Tom Jones:4424:5/12/66:543354

Mary Adams:5346:11/4/63:28765

Sally Chang:1654:7/22/54:650000

Billy Black:1683:9/23/44:336500

$ awk ‘{print $1,$2}‘ employees2

Tom Jones:4424:5/12/66:543354

Mary Adams:5346:11/4/63:28765

Sally Chang:1654:7/22/54:650000

Billy Black:1683:9/23/44:336500

$ awk -F: ‘{print $1,$2}‘ employees2

Tom Jones 4424

Mary Adams 5346

Sally Chang 1654

Billy Black 1683

舉例2:多個(gè)域分隔符。如果使用多個(gè)域分隔符,要將其封裝在方括號(hào)里。

$ nawk -F‘[ :\t]‘ ‘{print $1,$2,$3}‘ employees2

Tom Jones 4424

Mary Adams 5346

Sally Chang 1654

Billy Black 1683

解釋:把空格、制表符、冒號(hào)當(dāng)成輸入域分隔符。

輸出域分隔符:默認(rèn)的輸出域分隔符用逗號(hào)來(lái)分隔,被分隔的域之間打
印一個(gè)空格,如果域之間沒(méi)有逗號(hào),則打印時(shí)各域?qū)D在一起。




6.模式和操作
awk 模式(patterns)控制awk將對(duì)一行輸入作什么樣的操作。一個(gè)模式包括
一個(gè)正則表達(dá)式,一個(gè)產(chǎn)生正確或者錯(cuò)誤條件的表達(dá)式,或者它們的組合。
默認(rèn)操作時(shí)打印模式中符合表達(dá)式條件的各行。當(dāng)讀入一個(gè)模式時(shí),有一條
隱含的if語(yǔ)句。如果if語(yǔ)句是隱含的,周圍可以沒(méi)有花括號(hào)。

例子:

$ awk ‘$3<4000‘ employees

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

解釋:如果第3個(gè)域小于4000,則打印該域。

操作:操作(actions)是封裝在花括號(hào)里且由分號(hào)分隔的語(yǔ)句。如果一個(gè)模式
在一個(gè)操作之前,則該模式規(guī)定了何時(shí)執(zhí)行該操作。

舉例:

$ awk ‘/Tom/{print "Hello there," $1}‘ employees

Hello there,Tom

解釋:如果記錄中包含Tom,則打印Hello there,Tom


7.正則表達(dá)式



一個(gè)正則表達(dá)式對(duì)awk來(lái)說(shuō)是一個(gè)由封裝在正斜杠里的字符組成的模式。Awk
支持的正則表達(dá)式與egrep基本一樣,可以參考表3.1和表3.2。

舉例:

$ nawk ‘/^Mary/‘ employees

Mary Adams 5346 11/4/63 28765

解釋:顯示employees文件中以Mary開頭的行

$ nawk ‘/^[A-Z][a-z]* /‘ employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

解釋:顯示行開頭是一個(gè)大寫字母,然后跟一個(gè)或多個(gè)小寫字母,再跟一個(gè)
空格。

匹配操作符(~)、否定號(hào)(!)用來(lái)與以條記錄或域里的表達(dá)式相匹配。

例子:

$ awk ‘$1 ~/[Bb]ill/‘ employees

Billy Black 1683 9/23/44 336500

解釋:awk將顯示第一個(gè)域里與Bill或者bill相匹配的行

$ awk ‘$1 !~/ly$/‘ employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

解釋:顯示第一個(gè)域中末尾不是ly的所有行。


8.寫在命令表文件中的awk命令
寫awk命令表的方法可以參考chap05/info文件。該文件內(nèi)容如下:

# Here is a sample script:

#****************************************************************
*

# My first awk script by Jack Sprat

# Script name: info; Date: February 28, 1999

/Tom/{print "Tom‘s birthday is " $3}

/Mary/{print NR, $0}

/^Sally/{print "Hi Sally, " $1 " has a salary of $" $4 "."}

#End of script


9.練習(xí)題參考答案
習(xí)題文件是chap05/donors,部分內(nèi)容如下:

Mike Harrington510) 548-1278:250:100:175

Christian Dobbins40 538-2358:155:90:201

Susan Dalsass206) 654-6279:250:60:50

Archie McNichol206) 548-1348:250:100:175

上面的數(shù)據(jù)庫(kù)包含名字、電話號(hào)碼和過(guò)去三個(gè)月的競(jìng)選捐款。


1〉打印所有的電話號(hào)碼


$ awk -F: ‘{print $2}‘ donors
2〉打印Dan的電話號(hào)碼


$ awk -F: ‘/^Dan/{print $2}‘ donors



3〉打印Susan的名字和電話號(hào)碼


$ nawk -F‘[ :\t]‘ ‘/^Susan/{print $1,$3,$4}‘ donors
4〉打印所有以D開頭的姓


$ awk ‘$2 ~/^D/{print $2}‘ donors
5〉打印所有以一個(gè)C或E開頭的名


$ awk ‘/^[CE]/{print $1}‘ donors
6〉打印所有只有四個(gè)字符的名


$ nawk ‘/^[A-Z][a-z][a-z][a-z] /{print $1}‘ donors
7〉打印所有那些區(qū)號(hào)是916的名


$ awk -F: ‘$2 ~/916/{print $1}‘ donors
8〉打印Mike的活動(dòng)捐款。打印每個(gè)值時(shí)都要以一個(gè)美元符號(hào)打頭;例如:
$500$200$300


$ awk -F: ‘/^Mike/{printf "$%d$%d$%d\n",$3,$4,$5}‘ donors
9〉打印姓,其后跟一個(gè)逗號(hào)和名


$ nawk -F‘[ :\t]‘ ‘{printf "%s,%s\n",$2,$1}‘ donors
10〉 寫一個(gè)叫facts的awk命令表,它能:
a. 打印Savages的全名和電話號(hào)碼
b. 打印Chet的捐款
c. 打印所有第一個(gè)月捐款$250的人


文件內(nèi)容如下:
$ cat facts

#My first awk scripts by wangzhh.

/Savage/{print $1,$2}

/^Chet/{printf "Beneficence of Chet: $%d$%d$%d\n",$3,$4,$5}

$3 ~/250/{printf "erson who‘s beneficence is 250:%s\n",$1}

調(diào)用方法:

nawk -F: -f facts donors







第6章 awk實(shí)用程序:awk編程結(jié)構(gòu)

比較表達(dá)式比較行,如果行里的條件為真,就執(zhí)行操作。如果給表達(dá)式求值
為真則值等于1,反之等于0。




1.關(guān)系操作符
下表列出了關(guān)系操作符。




操作符

含義

例子

<

小于

x<y

<=

小于等于

x<=y

==

等于

x==y

!=

不等于

x!=y

>;=

大于等于

x>;=y

>;

大于

x>;y

~

與正則表達(dá)式相匹配

x~/y/

!~

不與正則表達(dá)式相匹配

x!~/y/



表6.1關(guān)系操作符

關(guān)系操作符舉例:

$ cat employees

Tom Jones 4423 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

$ awk ‘$3==4423‘ employees

Tom Jones 4423 5/12/66 543354

$ nawk ‘$3 >;5000{print $1}‘ employees

Mary

$ nawk ‘$2 !~/Adam/‘ employees

Tom Jones 4423 5/12/66 543354

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

條件表達(dá)式:一個(gè)條件表達(dá)式用兩個(gè)符號(hào),問(wèn)號(hào)和冒號(hào)來(lái)給表達(dá)式求值。與
一個(gè)if/else語(yǔ)句相比更簡(jiǎn)介。

2.條件表達(dá)式
格式:

conditional expression1?expression2:expression3

它等同于{if(expression1)

expression2

else

expression3

}

條件表達(dá)式舉例:

nawk ‘{max=($1>;$2)?$12;print max}‘ employees

解釋:如果第一個(gè)域大于第二個(gè)域,就把第一個(gè)域的內(nèi)容賦給max,反之把第
二個(gè)域的內(nèi)容賦給max,然后打印max





3.計(jì)算
可以在模式里執(zhí)行計(jì)算。awk以浮點(diǎn)方式執(zhí)行所有的算術(shù)運(yùn)算。




操作符

含義

例子

+



x+y

-



x-y

*



x*y

/



x/y

%

求模

x%y

^

冪運(yùn)算

x^y



表6.2 算術(shù)運(yùn)算操作符

4.復(fù)合模式
復(fù)合模式 (compound patterns) 是把模式和邏輯操作符相結(jié)合的表達(dá)式,給
一個(gè)表達(dá)式從左到右求值。




操作符

含義

例子

&&

邏輯與

a&&b

||

邏輯或

a||b

!

邏輯非

!a



表6.3 邏輯操作符

復(fù)合模式舉例:

$ nawk ‘$3>;4000 && $3<=6000‘ employees

Tom Jones 4423 5/12/66 543354

Mary Adams 5346 11/4/63 28765

$ nawk ‘!($3>;4000 && $3<=6000)‘ employees

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

5.范圍模式
范圍模式從一個(gè)模式的第一次出現(xiàn)匹配到第二個(gè)模式的第一次出現(xiàn),然后從
第一個(gè)模式的第二次出現(xiàn)匹配到第二個(gè)模式的第二次出現(xiàn)等等。如果第一個(gè)
模式被匹配,而第二個(gè)模式?jīng)]有找到,則awk將顯示直到末尾的所有行。

例子:

$ cat datafile

northwest NW Joel Craig 3.0 .98 3 4

western WE Sharon Kelly 5.3 .97 5 23

southwest SW Chris Foster 2.7 .8 2 18

southern SO May Chin 5.1 .95 4 15

southeast SE Derek Johnson 4.0 .7 4 17

eastern EA Susan Beal 4.4 .84 5 20

northeast NE TJ Nichols 5.1 .94 3 13

north NO Val Shultz 4.5 .89 5 9

central CT Sheri Watson 5.7 .94 5 13

$ nawk ‘/^north/,/^west/‘ datafile

northwest NW Joel Craig 3.0 .98 3 4

western WE Sharon Kelly 5.3 .97 5 23

northeast NE TJ Nichols 5.1 .94 3 13





north NO Val Shultz 4.5 .89 5 9

central CT Sheri Watson 5.7 .94 5 13


6.一個(gè)數(shù)據(jù)有效性檢查程序
本例子使用chap06/passwd文件,內(nèi)容如下:

tooth:pwHfudo.eC9sM:476:40:Contract Admin.:/home/rickenbacker/tooth:/bin/csh

lisam:9JY7OuS2f3lHY:4467:40isa M. Spencer:/home/fortune1/lisam:/bin/csh

goode:v7Ww.nWJCeSIQ:32555:60:Goodwill Guest User:/usr/goodwill:/bin/csh

bonzo:eTZbu6M2jM7VA:5101:911: SSTOOL Log account :/home/sun4/bonzo:/bin/csh

info:mKZsrioPtW9hA:611:41:Terri Stern:/home/chewie/info:/bin/csh

cnc:IN1IVqVj1bVv2:10209:41:Charles Carnell:/home/christine/cnc:/bin/csh

bee:*:347:40:Contract Temp.:/home/chanel5/bee:/bin/csh

friedmanyuIiKoFTV0TE:3561:50:Jay Friedman:/home/ibanez/friedman:/bin/csh

chambers:Rw7R1k77yUY4.:592:40:Carol Chambers:/usr/callisto2/chambers:/bin/csh

gregc:nkLulOg:7777:30:Greg Champlin FE Chicago

ramona:gbDQLdDBeRc46:16660:68:RamonaLeininge MWA CustomerService Rep:/home/forsh:/bin/csh

要求程序能夠顯示域個(gè)數(shù)不等于7的行、第一個(gè)域不包含數(shù)字字母的行、第
二個(gè)域等于星號(hào)的行。程序?qū)懺趀x_6.8.nawk文件中,內(nèi)容如下:

# nawk script (covered later in the chapter)

# To demonstrate example 6.8 using this script, run

# % nawk -f ex_6.8.nawk passwd

BEGIN {FS = ":"}

NF != 7 { printf("line %d, does not have 7 fields: %s\n",NR,$0)}

$1 !~ /[A-Za-z0-9]/{printf("line %d, nonalphanumeric user id: %s\n"NR,$0)}

$2 == "*" {printf("line %d, no password: %s\n",NR,$0)}

下面是調(diào)用方法和執(zhí)行結(jié)果:

$ awk -f ex_6.8.nawk passwd

line 7, no password: bee:*:347:40:Contract Temp.:/home/chanel5/bee:/bin/csh

line 10, does not have 7 fields: gregc:nkLulOg:7777:30:Greg Champlin FE Chicago


7.練習(xí)題參考答案
聯(lián)系文件是chap06下的lab4.data,內(nèi)容如下:

Mike Harrington510) 548-1278:250:100:175

Christian Dobbins40 538-2358:155:90:201

Susan Dalsass206) 654-6279:250:60:50

Archie McNichol206) 548-1348:250:100:175

Jody Savage206) 548-1278:15:188:150

Guy Quigley916) 343-6410:250:100:175

Dan Savage:(406) 298-7744:450:300:275

Nancy McNeil:(206) 548-1278:250:80:75

John Goldenrod:(916) 348-4278:250:100:175

Chet Main:(510) 548-5258:50:95:135

Tom Savage:(40 926-3456:250:168:200

Elizabeth Stachelin:(916) 440-1763:175:75:300


1>; 打印那些第一個(gè)月捐款超過(guò)100的人的姓名





$ awk -F: ‘$3>;100 {print $1}‘ lab4.data


2>; 打印那些第一個(gè)月捐款少于$60的人的姓名和電話號(hào)碼


$ awk -F: ‘$3<60{print $1,$2}‘ lab4.data
3>; 打印那些第三個(gè)月捐款在90到150之間的人


$ awk -F: ‘$5>;=90 && $5<=150 {print $0}‘ lab4.data
4>; 打印那些三個(gè)月捐款在800以上的人


$ awk -F: ‘$3+$4+$5>;800 {print $0}‘ lab4.data
5>; 打印那些平均每月捐款大于$150的人名和點(diǎn)話號(hào)碼


$ nawk -F‘[ :\t]‘ ‘($5+$6+$7)/3>;150{print $1,$3,$4}‘ lab4.data
6>; 打印那些區(qū)號(hào)不是916的人名


$ nawk -F‘[ :\t]‘ ‘$3 !~/916/{print $1}‘ lab4.data
7>; 打印每條記錄,記錄號(hào)在前面


$ awk ‘{print NR,$0}‘ lab4.data
8>; 打印每個(gè)人的名字和捐款總額
$ nawk -F‘[ :\t]‘ ‘sum=($5+$6+$7) {print $1,sum}‘ lab4.data


9>; 把Elizabeth的第二次捐款加上$10


$ nawk -F‘[ :\t]‘ ‘juankuan=($1 ~/Elizabeth/)?$6+106{print $1,juankuan}‘ lab4.data
10>;把Nancy McNeil的名字改成Louise McInnes
$ nawk ‘name=($1 ~/Nancy/)?"Louise McInnes"1{print name}‘ lab4.data







第7章 awk實(shí)用程序:awk編程
1.變量
.. 數(shù)值和串常數(shù)
數(shù)值常數(shù)可以表示成整數(shù)、浮點(diǎn)、科學(xué)計(jì)數(shù)等。含有空格的串要封裝在
雙引號(hào)里。例如"Hello world"。如果一個(gè)域或這數(shù)組元素為空,則串值
為空。一個(gè)空行也被當(dāng)作空串。


.. 用戶自定義變量
用戶自定義變量包括字母、數(shù)字和下劃線,且不能以數(shù)字開頭。在awk
中變量不用聲明,awk通過(guò)表達(dá)式的上下文推斷變量類型,并且如果需
要,還可以在不同類型的變量中相互轉(zhuǎn)換。


.. 遞加和遞減操作符(++和--)
與c++語(yǔ)言中一樣。x++是后遞加,++x是先遞加。


.. 內(nèi)置變量。
內(nèi)值變量要大寫,他們可以用在表達(dá)式里而且可以被重置。如下表






變量名

含義

ARGC

命令行變?cè)獋€(gè)數(shù)

ARGV

命令行變?cè)M數(shù)

FILENAME

當(dāng)前輸入文件名

FNR

當(dāng)前文件里的記錄號(hào)

FS

輸入域分隔符,默認(rèn)是空格

NF

當(dāng)前域里的域個(gè)數(shù)

NR

到目前為止的記錄數(shù)

OFMT

數(shù)值輸出格式

OFS

輸出域分隔符

ORS

輸出記錄分隔符

RLENGTH

由match函數(shù)匹配的串的長(zhǎng)度

RS

輸入記錄分隔符

RSTART

由match函數(shù)匹配的串偏移量

SUBSEP

下標(biāo)分隔符



表7.2 nawk內(nèi)置變量

內(nèi)置變量舉例:

$ nawk -F: ‘$1=="Mary Adams"{print NR,$1,$2,$NF}‘ employees2

2 Mary Adams 5346 28765

解釋:-F選項(xiàng)把分隔符改成冒號(hào)。如果域1等于Mary Adams,則打印記
錄號(hào)、第一個(gè)域、第二個(gè)域和最后一個(gè)域($NF)

.. BEGIN模式
BEGIN模式后面跟一個(gè)操作模塊,在awk處理文件之前執(zhí)行該模塊。BEGIN
模式主要用來(lái)設(shè)置OFS、RS、FS等內(nèi)置變量的值。




$ awk ‘BEGIN{FS=":";OFS="\t";ORS="\n\n"}{print $1,$2,$3}‘ employees2

Tom Jones 4423 5/12/66



Mary Adams 5346 11/4/63




Sally Chang 1654 7/22/54



Mary Black 1683 9/23/44

解釋:在處理輸入文件之前,把域分隔符置成一個(gè)冒號(hào),輸出域分隔符
制成跳格符,并把輸出記錄分隔符(ORS)設(shè)置成兩個(gè)換行符。

.. END模式
END模式不與任何輸入行相匹配,但是執(zhí)行任何與END模式相關(guān)的操作。
在所有行處理完畢之后再來(lái)處理END模式。




$ awk ‘/Mary/{count++}END{print "Mary was found " count " times."}‘ employees

Mary was found 1 times.

解釋:對(duì)于包含Mary的每一行,count變量值都遞增1。awk 處理完畢之
后,END模塊打印結(jié)果。

2.重定向和管道
.. 輸出重定向:當(dāng)把輸出從awk重定向到一個(gè)UNIX文件時(shí),使用shell
重定向操作符。如果重定向操作符用在awk命令里面則必須將重定向文
件用雙引號(hào)括起來(lái)。例如:


$ awk ‘$4>;70 {print $1,$2 >;"passing_film"}‘ datafile
.. 輸入重定向(getline)
getline 函數(shù)用來(lái)從標(biāo)準(zhǔn)輸入,例如管道或者文件來(lái)讀入數(shù)據(jù),而不是
從正被處理的當(dāng)前文件。getline 取得輸入的下一行,并更新NF、NR
和FNR等內(nèi)置變量的值。如果getline找到記錄則返回1,達(dá)到EOF(文
件結(jié)束)則返回0。如果有錯(cuò)誤則返回-1。


.. 舉例1:
$ nawk ‘BEGIN{"date"|getline d;print d}‘ datafile

2005年05月06日 星期五 15時(shí)05分41秒 CST

解釋:執(zhí)行date命令,然后把輸出從管道送到getline,并賦給自
定義變量d,然后打印d。


.. 舉例2:
$ nawk ‘BEGIN{while("ls"|getline) print}‘

awk.sc2

datafile

datafile2

employees

employees2

lab5.data

names

passwd

解釋:將把ls的輸出送到getline。對(duì)于每次循環(huán),getline都從
ls讀取一個(gè)以上輸出,然后打印到屏幕上


.. 舉例3:
$ nawk ‘BEGIN{printf "What is your name?";\

>; getline name<"/dev/tty"}\

>; $1 ~ name {print "Found " name " on line ",NR "."}\

>; END{print "See ya, " name "."}‘ employees









What is your name?Wangzhonghai

See ya, Wangzhonghai.

解釋:將在屏幕上打印What is your name?,并且等待用戶響應(yīng)。
getline 函數(shù)將從終端(/dev/tty)接受輸入,一直到輸入一個(gè)換行
符為止,然后把輸入存到用戶自定義變量name中。如果遞一個(gè)域和
name的值相匹配,則執(zhí)行print函數(shù)。在END模式中打印”See ya,”
然后跟name的值。


.. 舉例4
$ nawk ‘BEGIN{while (getline<"/etc/passwd">;0)lc++;print lc}‘

16

解釋:awk將從“/etc/passwd”讀取各行,lc遞增,直到EOF,然
后打印lc的值。






3.管道
如果在一個(gè)awk程序中打開一個(gè)管道,則必須在打開另一個(gè)之前先關(guān)閉它。
在管道符號(hào)由變的命令封裝在雙引號(hào)里。一次只能打開一個(gè)管道。下面的例
子是將names文件中的姓名按照姓作為第一關(guān)鍵字,名作為第二關(guān)鍵字來(lái)進(jìn)
行倒排序:

$ awk ‘{print $1,$2|"sort -r +1 -2 +0 -1 "}‘ names

tony tram

john smith

dan savage

barbara nguyen

elizabeth lone

john goldenrod

susan goldberg

george goldberg

eliza goldberg

alice cheba


4.關(guān)閉文件和管道
如果在awk中再次使用一個(gè)文件或者管道來(lái)讀取或?qū)懭?,則需要首先關(guān)閉管
道。打開和關(guān)閉管道的例子可以參考/chap07/awk.sc3文件。(書中源代碼沒(méi)
有這個(gè)文件,而書上錯(cuò)誤很多。)


5.回顧(略)
6.條件語(yǔ)句
1) if 語(yǔ)句
以if結(jié)構(gòu)開頭的語(yǔ)句是操作語(yǔ)句。在條件模式(conditional patterns)
里,if是隱含的;在一個(gè)條件操作語(yǔ)句中,if要顯式說(shuō)明,并且后面跟
一個(gè)封裝在括弧里的表達(dá)式。如果跟在條件表達(dá)式后面的語(yǔ)句不止一條,
則語(yǔ)句組必須放在花括號(hào)里,并且用分號(hào)或者換行符來(lái)分開。

格式:

if (expression){statement;statement;…}

舉例1:

$ nawk ‘{if($8>;15) print $1 " To high"}‘ datafile

舉例2:







$ nawk ‘{if($8>;15 && $8<=23){safe++; print $1 " OK " safe}}‘ datafile


2) if/else語(yǔ)句
if/else語(yǔ)句允許一個(gè)二路判斷。

格式:

{if(expression) {

statement;statement;…

}

else{

statement;statement;…

}

}


3) if/else else if語(yǔ)句
允許多路判斷。

格式:

{if (expression) {

statement;statement;…

}

else if (expression){

statement;statement;…

}

else if (expression){

statement;statement;…

}

else{

statement;statement;…

}

}




7.循環(huán)
循環(huán)的作用是,如果一個(gè)條件為真,則重復(fù)執(zhí)行測(cè)試表達(dá)式后的語(yǔ)句。循環(huán)
通常用來(lái)迭代一條記錄里的域,及循環(huán)操作END模塊里的一個(gè)數(shù)組的元素。
awk 有3種循環(huán):while循環(huán)、for循環(huán)和特殊for循環(huán)。


1) while循環(huán)
使用規(guī)則與c中一樣。

舉例:

$ nawk ‘{i=1;while(i<=NF){print NF,$i;i++}}‘ datafile

解釋:變量i初始化為1;當(dāng)I小于或等于記錄中的域個(gè)數(shù)(NF)時(shí),執(zhí)行
print并讓i遞增,然后再測(cè)試表達(dá)式,直到i>;NF。讀取下一條的記錄的
時(shí)候i被重新初始化。


2) for循環(huán)
使用規(guī)則與c中一樣。

舉例:

$ nawk ‘{ for (i=1;i<=NF;i++) print NF,$i}‘ datafile


3) 循環(huán)控制:break和continue
break 和 continue。break 讓你在某個(gè)條件為真時(shí)調(diào)出循環(huán)。continue







使循環(huán)在某個(gè)條件為真時(shí)條過(guò)后面的任何語(yǔ)句,并把控制返回循環(huán)頂部,
開始下一次迭代。

舉例:

{for (x=3;x<=NF;x++)

if($x<0){print "Bottomed out!";break}

#breaks out of for loop

}

舉例2:

{for (x=3;x<=NF;x++)

if($x==0){print "Get next item!";continue}

#starts next item of for loop

}




8.程序控制語(yǔ)句
1) next 語(yǔ)句
next 語(yǔ)句從輸入文件取得下一個(gè)輸入行,在awk命令表頂部重新開始執(zhí)
行。

舉例:

$ awk ‘{if($1 ~/Tom/){next} else {print}}‘ db

解釋:如果第一個(gè)域包含Tom,則略過(guò)。


2) exit語(yǔ)句
exit 語(yǔ)句用來(lái)終止awk程序。它停止處理記錄,但是不跳過(guò)END語(yǔ)句。


3)


9.?dāng)?shù)組
在awk中數(shù)組叫做關(guān)聯(lián)數(shù)組(associative arrays),因?yàn)橄聵?biāo)記可以是數(shù)也
可以是串。awk中的數(shù)組不必提前聲明,也不必聲明大小。數(shù)組元素用0或
空串來(lái)初始化,這根據(jù)上下文而定。


1) 關(guān)聯(lián)數(shù)組的下標(biāo)
.. 把變量用作數(shù)組索引。
舉例:

$ nawk ‘{name[x++]=$2};END{for(i=0;i<NR;i++)\

>; print i,name}‘ employees

0 Jones

1 Adams

2 Chang

3 Black

解釋:在數(shù)組name里的下標(biāo)是一個(gè)用戶自定義變量x。++顯示了一個(gè)
數(shù)值型的上下文。


.. 特殊for循環(huán)
在for循環(huán)無(wú)效的情況下,即當(dāng)串被用作下標(biāo)或者下標(biāo)不是連續(xù)的數(shù)
時(shí),用特殊for循環(huán)來(lái)讀取一個(gè)關(guān)聯(lián)數(shù)組。特殊for循環(huán)把下標(biāo)當(dāng)作
一個(gè)鍵來(lái)找到它的相關(guān)的值。

格式:

{for(item in arrayname){

print arrayname[item]}}









舉例:

$ nawk ‘/^Tom/{name[NR]=$1};\

>; END{for(i=1;i<=NR;i++) print name}‘ db

Tom







Tom

Tom



Tommy

$ nawk ‘/^Tom/{name[NR]=$1};\

>; END{for(i in name){print name}}‘ db

Tom

Tom

Tommy

Tom

解釋:這兩個(gè)例子用NR(行號(hào))來(lái)做下標(biāo),因此匹配Tom的模式的行
不連續(xù),數(shù)組下標(biāo)不連續(xù)。如果用傳統(tǒng)for來(lái)循環(huán)打印會(huì)在數(shù)組沒(méi)有
值的地方打印空值。通過(guò)使用特殊for循環(huán),只打印數(shù)組中有值的內(nèi)
容。


..


2)


10.








附錄B 比較三種shell

特性

C shell

Bounne shell

Korn shell

變量

給局域變量賦


set x=5

s=5

s=5

賦變量屬性





typeset

給環(huán)境變量賦


setenv NAME Bob

NAME=Bob

export NAME=Bob

存取變量

echo $NAME

set var=net

echo ${var}work

network

echo $NAME

var=net

echo ${var}work

network

echo $NAME或print
$NAME

var=net

print ${var}work

network

專用
變量

該進(jìn)程的PID

$$

$$

$$

退出狀態(tài)

$status

$?

$?

上一個(gè)后臺(tái)作
業(yè)



$!

$!

數(shù)組

給數(shù)組賦值

Set x=(a b c)

N/A

Y[0]=a;y[1]=b;y[2]=c

Set –A fruit apples
pears plums



__________________________________

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
運(yùn)維常用linux命令\shell技巧范例
《shell編程指南》讀書筆記(三)——文本處理(正則表達(dá)式,grep,awk,sed)
Linux三劍客及使用介紹
linux 文本編輯命令grep sed awk(轉(zhuǎn)) - linux開發(fā) - gliet...
Linux必學(xué)技能:文本操作三劍客(awk/sed/grep)應(yīng)用實(shí)例
高級(jí)Unix命令 | 酷殼 - CoolShell.cn
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服