1. 程式人生 > >二十八、awk

二十八、awk

awk

二十八、awk

awk:流式編輯器,針對文檔的行進行操作。awk兼具sed的所有功能,且更強大。可以對每段做匹配,不能更改文件內容,不像sed有-i選項能更改內容。

截取文檔中的某段,示例:

-F:指定分隔符,若不加-F,則以空格或tab為分隔符。print為打印的動作,用來打印某個字段。$1為第一個字段,以此類推,$0表示整行

# awk -F ':' {print $1} test.txt 打印第一段

# head -n2 test.txt |awk -F ':' '{print $1}' 打印前兩行的第一段

# head -n2 test.txt |awk -F ':' '{print $0}' 打印前兩行整行(所有段)

# awk -F ':' '{print $1,$2,$4}' test.txt 多打印幾段,用逗號隔開;也可用#,但是#麻煩一點,要用雙引號括起來,示例:

# awk -F ':' '{print $1"#"$2"#"$4}' test.txt

root#x#0

bin#x#1

daemon#x#2

# awk -F ':' '{print $0}' test.txt 打印所有行

不指定分隔符,示例:

# awk '{print $1}' 1.txt

1

aa

cc

# cat 1.txt

1 2

aa bb

cc d

匹配字符或字符串

# awk '/ot/' test.txt 指定字符為ot

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologi

# awk -F ':' '$1 ~/oo/' test.txt

root:x:0:0:root:/root:/bin/bash

精確匹配,第一段裏包含oo的行,1後加個~

。~為匹配的意思。這就是比grep和sed更強大的地方,對段匹配。同樣也支持正則,如o+,o*等等。所有符號都不用加脫義字符,這是awk比grep和sed方便的地方。

# awk -F ':' '/root/ {print $1,$2} /user/ {print $1,$2}' test.txt 多次匹配

先匹配root,再匹配user。

條件操作符

邏輯符號判斷,==為等於,還有>、>=、<、<=、!=等,!=為不匹配。若把比較的數字用雙引號括起來,awk會認為是字符,不括起來會認為是數字。

# awk -F ':' '$3=="0"' test.txt

# awk -F ':' '$3>="0"' test.txt

# awk -F ':' '$3>=500' test.txt

匹配數字時不要加雙引號,否則認為是字符

# awk -F ':' '$7!="/sbin/nologin"' test.txt 是字符串,所以要加上雙引號

# awk -F ':' '$3<$4' test.txt 兩個段之間進行邏輯比較,第三段小於第四段

||和&&,分別表示“或者”,“並且”。示例:

# awk -F ':' '$3<"4" && $3<"7"' test.txt

此處4和7代表字符,所以要用雙引號括起來。

# awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt

第三段大於1000,或者第七段等於/bin/bash的。

# awk -F ':' '$3>1000 || $7 ~ /bash/' test.txt

匹配第七段為bash的,或者第三段大於1000的。

awk的內置變量

awk常用變量:OFS、NF和NR。

OFS:和-F選項有類似的功能,也是用來定義分隔符的,但是它是在輸出的時候定義。

NF:表示用分隔符分隔後一共有多少段

NR:表示行號

OFS用法示例:

# head -n5 test.txt |awk -F ':' '{OFS="#"} {print $1,$3}'

定義分隔符為#,也可以定義為@

root#0

bin#1

daemon#2

adm#3

lp#4

更高級的用法,示例:

# awk -F ':' '{OFS="#"} {if ($3<1000) {print $1,$3,$4}}' /etc/passwd

if:如果,判斷的作用。如果$3<1000 則打印出 $1$3$4 ,輸出並以#分隔顯示。

NF用法示例:

# awk -F ':' '{print NF":" $0}' test.txt 顯示所有段有多少段。

# awk -F ':' 'NF==7 && $1 ~ /root|sync/' test.txt 配合匹配一起用

# head -n3 /etc/passwd |awk -F ':' '{print NF}'

7

7

7

# head -n3 /etc/passwd |awk -F ':' '{print $NF}'

/bin/bash

/sbin/nologin

/sbin/nologin

此處NF是多少段,$NF是最後一段的值。

NF:表示用分隔符分隔後一共有多少段

NR用法示例:

# awk -F ':' '{print NR":" $0}' test.txt 顯示所有段的行號

# head -n3 /etc/passwd |awk -F ':' '{print NR}'

1

2

3

# awk -F ':' 'NR<=10' test.txt 前十行,NR可作為判斷條件。

NR也可配合段匹配一起使用,示例:

# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt

NR:表示行號

# awk -F ':' '{print $NR":"$NF}' test.txt 顯示出的內容將從$1開始往後推。

awk中的數學運算

awk可以更改段值,示例:

# head -n3 test.txt | awk -F ':' '$1="root"'

root x 0 0 root /root /bin/bash

root x 1 1 bin /bin /sbin/nologin

root x 2 2 daemon /sbin /sbin/nologin

# head -n3 test.txt | awk -F ':' '{OFS=":"} $1="root"'

root:x:0:0:root:/root:/bin/bash

root:x:1:1:bin:/bin:/sbin/nologin

root:x:2:2:daemon:/sbin:/sbin/nologin

此處是一個等於號,是賦值的意思,兩個等於號就是匹配出來的意思,要分清楚。可以看到前三行的第一段都變為了root。可以直接定義分隔符為“:”。

計算某個段的總和,示例:

# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt

4610

(表示每一行的第三段相加,最後再print求和)

END:awk特有語法,表示所有的行都執行。

if:判斷。

for:循環。

# awk -F ':' '{if ($1=="root") {print $0}}' test.txt

root:x:0:0:root:/root:/bin/bash

先判斷第一段有root的,再打印整行。


二十八、awk