1. 程式人生 > >L-1-23 awk&sed

L-1-23 awk&sed

+ - 流編輯器 his mat 正則 string gin cas inittab

[awk]

awk <option> '<PATTERN> {<action>}' <filename> [<filename2> ...] //文本處理工具

比如:df -Ph |awk '{print $1,$3}'

//awk中大括號中應該用雙引號


awk會去分割每行並成分為字段,如:

this is a cat.

$1 $2 $3 $4

$4就是cat.

$0代表這一整行


******************<option>******************

-F<interpunction> //指定分隔符,可以用雙引號括起來

比如:awk -F: {print $1,$3} /etc/passwd //passwd文件中字段是由:分開的而不是由空格分開的。多個分割符連在一起時只算一個。(cut是算多個)


-v <var>="<string>" //awk可以設置內置變量,-v用來設置內置變量

也可以這樣表達awk 'BEGIN{a="Hello"};{print a}' //這裏多語句用;分開



*****************內置變量******************* //內置變量在大括號中直接寫,雙引號內的是字符串

FS 輸入分割符,默認是空格


OFS 輸出分割符,寫print命今時,$<num>之間用,分開的,默認是空格,但改後就有變化

如:awk -F: '{OFS="#"}{print $1,$2}' /etc/passwd


RS 輸入換行符,默認是回車


ORS 輸出換行符,默認是回車


FNR 當前處理文件的行數,單文件時處理到第幾行就是第幾行。


NR 所有文件處理的行數,用於多文件時使用

如:awk 'END{print NR}' /etc/passwd /etc/fstab //顯示passwd和fstab一共幾行


NF 當前處理行的分割成的字段數。$NF是當前行的最後一個字段




*****************<PATTERN>**************** //類似於sed的address,決定需要操作的行

/<RegExp>/ //正則表達式,要用斜杠括起來,只對符合條件的行進行操作

如:awk -F: '/r..t/{print $1}' /etc/passwd //以包含/r..t/表達式的行作為目標,將它們打印出來


<expression> //表達式,只對符合條件的行進行操作

如:awk -F: '$3 >= 500{print $1,$3}' /etc/passwd //在passwd文件中$3代表UID,這裏比較UID是否大於500,並打印出大於500的用戶名和UID

如:awk -F: '$7~bash${print $1,$7}' /etc/passwd //在passwd文件中$7是用戶的shell,這裏判斷$7是否以bash結尾,並打印出符合條件的用戶名與用的shell


<range> //指定範圍,與sed的指定範圍不太一樣。


{BEGIN|END} //表示命今只在開始或結束前施行一次。有了這個PATTERN,awk命令後面可以不跟文件

如:awk 'BEGIN{print "one\ntwo\nthree"}' //\n是換行符


<null> //什麽都不寫表示讀取所有行



********************表達式*********************

計算操作 用法如:awk 'BEGIN{print 1+1}'

有以下幾種:

-<num> 取負值


+<figure> 將非數字改成數字,boolean中是為1,否為0

如:awk 'BEGIN{a=+(6 > 7);print a}' 結果是0

awk 'BEGIN{a=+(7 > 6);print a}',結果是1


還有一些計算符與shell一致:+-*/^(次方)%(取余)


賦值操作符,用法如:awk 'BEGIN{i++;print i}'

這些與shell一致:= += -= *= /= ^= %= ++ --


布爾值,結果是True或False

如:< > == <= >=

!=(不等)

<string> ~ <pattern> //<string>是否滿足<pattern>,滿足為True

<string> !~ <pattern> //<string>是否滿足<pattern>,不滿足為True


邏輯關系符

和shell一樣:&& ||


條件表達式

<selector>?<if-true>:<if-false> //三目結構,判斷<selector>,結果為真值為<if-ture>,否則為<if-false>

如:awk 'BEGIN{a=3;b=4;max=a>b?a:b;print max}'


********************數組*************************

例子:awk -F: '{shell[$NF]++}END{for(A in shell){print A,shell[A]}}' /etc/passwd

這個數組裏第一個讀出的數組是shell[/bin/bash]這是中括號裏的下標可以是任何字符串,++代表shell[/bin/shell]的值變成1

第二行得到shell[/sbin/nologin]++,最後的循環時可以打印出下標A,這裏是下標/bin/bash,而shell[A]是/bin/bash用戶個數


******************<action>************************

print <item> 打印指定字段

如:awk -F: '{print $1}' /etc/passwd

awk -F: '{print NF}' /etc/passwd //參數NF不用打括號

awk 'BEGIN{print "Hello"}'


printf <format>,<item1>

%c ASCII碼形式顯示

%d,%i 十進制整數

%e,%E 科學計數法

%f 浮點數形式顯示

%g,%G 科學計數法浮點數形式顯示

%s 字符串形式表示

%u 無符號整數

%% %自身

修飾符

<num> 以<num>個數字來表示

- 左對齊 //不寫默認為右對齊

用法:awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd

%-15s是$1的格式,%i是$3,\n是換行


if <condition> <then> else <else_than>

如:awk -F: '{if ($1=="root") print $1;else print "not root"}' /etc/passwd


while <condition> {<command>;[<command> ..]}

如:awk -F: '{i=1;while(i<=3){print$i;i++}}' /etc/passwd


do-while {<command>} while <condition>

如:awk -F: '{i=q;do{print$i;i++}while(i<=3)}' /etc/passwd


for

如:awk -F: '{for(i=1;i<=3;i++)print$i}' /etc/passwd


case switch(<condition>) {case {<var>|<regexp>}:<command> [...] default:<command> }


break,continue 用法類似bash


next跳過當前行,直接進行下一行

如:awk -F: '{if($3%2==0)next;print $1;$3}' /etc/passwd

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

[sed]

sed '<AdressCommand>' <file> 流編輯器

-n 靜默模式,不在模式空間的內容。(只顯示修改的內容)

比如 sed '1p' /etc/passwd 結果是輸出第一行後再打輸出passwd文件

sed -n '1p' /etc/passwd 結果是只輸出第一行

-i 直接修改原文件

-e '<SCRIPT>' [-e <script>] ... :同時執行多個sed腳本

-f <file> :通過讀取一個文件來讀取裏面的sed腳本

-r 使用擴展正則表達式。

Address: //Address是選擇須要修改的行,Command是設置做什麽

1. StartLine,EndLine

eg: 1,100

//$表示最後一行,$-n表示最後第n行。

比如:sed '1,100d' <filename> //刪除<filename>的1-100行。

sed '1,$-3d' <filename> //比如一共5行,最後的第三行正好是第三行,所以是刪除前1-3行。

2. /RegExp/

eg: /^root/

//正則表達式來代表符合條件的行

比如:sed '/^root/d' <filename> //刪除文件中以root開頭的行

sed '/oot/d' /etc/passwd //刪除文件中帶有oot字符的行

3. /pattern1/,/pattern2/

//第一次被pattern1匹配到的行,至第一次被pattern2匹配到的行結束,中間的所有行進行操作。

比如:sed -n '/^root/,/^nobody/p' /etc/passwd //輸出root開頭的行到nobody開頭的行

4.LineNumber

//指精確的行

比如:sed '1d' <filename> //刪除第一行

5.StartLine,+N

//從startLine開始,向後的N行。共N+1行。

比如:sed -n '1,+3p' /etc/passwd //輸出passwd文件的第一行與接下來的三行。

sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root開頭的行,與此行接下來的3行下都追加hello

Command:

d:刪除符合條件的行。

p:顯示符合條件的行。

a \<string>:在指定的行後面追加新行,內容為“<string>”(\n 換行符)

比如:sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root開頭的行,與此行接下來的3行下都追加hello

sed '1,3a first line\nsecond line' /etc/passwd //在文件1-3行下各添加兩行first line second line

i \<string>:在指定的行前面追加新行,內容為“<string>”,與a類似。

r <file>: 將指定的文件內容添加至符合條件的行處

比如:sed '1r /etc/fstab' /etc/passwd //把fstab內容添加到passwd第一行下

w <file>: 將指定範圍內的內容另存為至指定文件。

s/<pattern>/<string>/<※> 查找每一行符合條件的<pattern>(能用正則表達式),並將每行中第一次匹配到的串替換成<string>。寫了s就不用寫address了,默認修改每一行。

※:g:全局替換。 //即替換所有,而不是每行第一個

i:忽略大小寫

eg:sed 's/oot/OOT/'/etc/fstab

eg:sed -r 's@^[[:space:]]+#@@g' /etc/inittab //s不一定是s///,也可以是s@@@、s###等其他特殊字符

string這裏可以使用&,代表了引用匹配的條目。

比如:正則表達式l..e,可能是like或是love,要它們匹配後都加r,那麽該寫成's/l..k/&r/',&代表了匹配的文字,它可以在任何地方,r&,1&1

sed 's#l\(..e\)#L\1#g' <filename> //只改括號內的部分,用了括號第二部分就可以引用。


比如說adress是2,command是p,那麽2p就是第二行的意思,sed -n '2p' <filename> 就是讀取文件的第二行。

如果需要修改的字符是特殊字符,那麽就需要\符轉譯:sed '/^\//d' /etc/fstab 刪除/開頭的行,其中\是特殊字符。


L-1-23 awk&sed