awk:基礎篇+案例

awk提供了很強大的功能,它是linux中功能最強大的數據處理引擎之一,它不只能夠對文本數據進行搜索分析處理排序,還能夠支持數學運算,含有內置函數和內置變量,甚至還能夠進行一些腳本處理,編程。能夠這麼說,它能夠根據發揮者的能力來起做用。mysql

awk在linux中其實並不叫awk,而叫gawklinux

[root@libin ~]# which awk
/bin/awk
[root@libin ~]# ls -l /bin/awk
lrwxrwxrwx. 1 root root 4 Jun 29 17:14 /bin/awk –> gawk 它是連接指向gawksql

awk的基本語法(基本格式):shell

awk  [option]…….'/PATTERN/{action}’ FILE…..編程

或者是awk [option]…..'script’ FILE……由於awk自己就是一個相似於解釋器的東西能夠解釋。bash

而有時候 '/PATTERN/{action}'就至關於'scrpit’ 至關於awk的腳本。ide

awk中的變量大體分兩種,一種是內置的變量,一種能夠容許你自定義變量。函數

awk的PATTERN有下列幾種涵義:this

PATTERN能夠作地址定界blog

起始行,結束行

/pattern1/,/pattern2/

還能夠特定某行

/pattern/

或直接加數字表示第幾行

另外PATTERN還支持表達式的功能

好比:表達式中支持:

>,<,<=,>=,!=,==,~(模式匹配的)

另外PATTERN中還有兩個比較特殊的一個是BEGIN,另外一個是END。

BEGIN表示在後面action以前要作的動做,這些動做能夠有初始化一些變量,在輸出最開始顯示一些東西。

而END表示後面action以後要作的動做。下面有示例

好比:取出系統上id號大於等於300的用戶有哪些?

[root@libin ~]# awk -F: '$3 >= 300{print $1,$3}' /etc/passwd
rtkit 499
saslauth 498
nfsnobody 65534
pulse 497
mageedu 500
bob 501
zabbix 496
jimmy 502

這裏筆者曾經犯過一次錯誤,筆者在寫awk的時候,並無加上-F: 分隔符,只是寫成awk ‘$3 >= 300{print $1,$3}' /etc/passwd 結果屏幕並無輸出正確的信息,只是顯示:

[root@libin ~]# awk '$3 >= 300 {print $1}' /etc/passwd
dbus:x:81:81:System
vcsa:x:69:69:virtual
avahi-autoipd:x:170:170:Avahi
rpcuser:x:29:29:RPC
nfsnobody:x:65534:65534:Anonymous
pulse:x:497:496:PulseAudio
zabbix:x:496:493:Zabbix

你們在這裏引覺得戒吧!

例子二、顯示用戶shell爲bash的用戶(可讓用戶作模式匹配)

[root@libin ~]# awk -F: '$7 ~ /bash$/{print $1,$7}' /etc/passwd (這裏模式匹配引用的內容必定要加//,如/要被引用的內容/

ageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash
mysql /bin/bash

例子三、在例子2的顯示內容以前加上一句話how are you

[root@libin ~]# awk -F: 'BEGIN{print "how are you"}$7 ~ /bash/ {print $1,$7}' /etc/passwd
how are you
root /bin/bash
mageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash

注意這裏若是想加入字串,必定要用雙引號引出來,否則就會變成這樣,好比筆者曾經忘記加雙引號,結果就顯示空白了。如

image

加上END試試:

awk -F: 'BEGIN {print "hello"}$7 ~ /bash$/{print $1,$7}END{print "thats all"}' /etc/passwd
hello
root /bin/bash
mageedu /bin/bash
bob /bin/bash
jimmy /bin/bash
bigbing /bin/bash
thats all

這裏曾經筆者也犯過一個錯誤:在被引用的字串裏使用了that’s all,就由於這個不起眼的 ’的符號,致使結果並無輸出出來。

image 因此通常沒有必要給本身找麻煩就不用特殊符號。


在awk有不少內置變量:

NF:Number of Field 字段數,直接引用則表示每一行中字段的總數,是個具體的數字。

FS:Field Seperator,輸入分隔符

OFS Output Field Seperator 輸出的分隔符

在示例中屢次引用passwd這個文件,可是屢次例子中輸出到屏幕上的分隔都是空格,如:

root /bin/bash
mageedu /bin/bash

若是我想讓它以原始的文本輸出到屏幕上的」:」號呢?

[root@libin ~]# awk 'BEGIN{FS=":";OFS=":"}$1~/root$/{print $1,$7}END{print "admin"}' /etc/passwd
root:/bin/bash
admin

這裏就用FS取代了-F選項,並指定輸出的分隔符爲:

 

 

在awk中,引用變量的值,不須要以$開頭,若是以$開頭的變量,則是引用變量中的字段的值。

awk大體的工做模式是這樣的:

image 若是不是特別說明,awk會默認以空白字符做爲分隔符,逐行的去作字符段的匹配。

而awk有本身內置的變量:舉例來講:

image  如左圖,假設line1有4個字段,默認以空白分隔符分隔,對於第一個字段,awk把它理解爲$1,第二個字段,理解爲$2,以此類推。這裏比較特殊一點就是$0,它表示所有字段的內容。咱們打個比方:

咱們寫一個示例:

[root@libin ~]# cat awk1.txt
tom and jerry are playing in the garden
[root@libin ~]#

這是一個只有一行的文本,下面用awk來進行取變量:

step一、先取出$1:

[root@libin ~]# awk -F' ' '{print $1}' ./awk1.txt 
tom                                                               若是沒有特殊要求,它默認是以空白爲分隔符的,因此-F ‘ ‘ 能夠進行省略。

[root@libin ~]# awk  '{print $1}' ./awk1.txt
tom

step二、取出第一和第三個字段

[root@libin ~]# awk '{print $1,$3}' ./awk1.txt
tom jerry                                                        這裏使用,號隔開的,其結果輸出到標準輸出(屏幕)上時,出現了tom jerry,這裏若是咱們不使用,會是什麼樣子的效果?

step三、若是在{}中$1和$3之間不加符號隔開

[root@libin ~]# awk '{print $1$3}' ./awk1.txt
tomjerry                                                         這裏tomjerry被粘合在了一塊兒

設想,若是咱們人爲的加些符號在裏面,能夠出現什麼效果呢?

[root@libin ~]# awk '{print $1-$3}' ./awk1.txt 這裏加上 - 符號
0
[root@libin ~]# awk '{print $1is$3}' ./awk1.txt 這裏加上了 is
tomjerry
[root@libin ~]# awk '{print $1&&$3}' ./awk1.txt 這裏加上&&符號
1
[root@libin ~]# awk '{print $1 $3}' ./awk1.txt  這裏加上了空白字符
tomjerry

輸出都不盡相同,可見符號在awk的{}有着不一樣的意思。之後在使用awk的時候務必要當心,不然一個不注意有可能就得不到想要的結果。

step四、若是我想整行都顯示出來

[root@libin ~]# awk '{print $0}' awk1.txt
tom and jerry are playing in the garden           這裏的效果相似grep ‘[[:alnum:]]\+’ awk1.txt

step五、有一個變量叫作NF,我若是在awk的program中寫入NF表示什麼呢?

[root@libin ~]# awk '{print NF}' awk1.txt
8

出現了數字8,再仔細看看文本中 tom and jerry are playing in the garden 以空格分開一共8段,原來NF表示每一行裏字段的總個數。

step五、那麼$NF是什麼呢?

[root@libin ~]# awk '{print $NF}' awk1.txt
garden                                                    對照tom and jerry are playing in the garden字段,原來$NF表示每一行裏最後一個字段的內容。

step六、顯示gid小於500的組

[root@libin ~]# awk -F: 'BEGIN{print "this is context"}$3 < 500{print $1,$3}' /etc/passwd
this is context
root 0
bin 1
daemon 2

或者

[root@libin ~]# awk 'BEGIN{FS=":";print "this is context"}$3 < 500{print $1,$3}' /etc/passwd
this is context
root 0
bin 1
daemon 2

step七、顯示默認shell爲nologin的用戶:

awk 'BEGIN{FS=":"}$7~/nologin$/{print$1,$7}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin

step八、顯示eth0網卡配置文件的配置信息,只顯示=後面的內容

[root@libin ~]# awk 'BEGIN{FS="="}{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0
eth0
dhcp
00:0c:29:7b:06:ec
yes
yes
Ethernet
172.16.249.126

step九、顯示/etc/sysctl.conf文件中定義的內核參數的參數名稱

[root@libin ~]# awk '$1~ /kernel.*/{print $1}' /etc/sysctl.conf
kernel.sysrq
kernel.core_uses_pid
kernel.msgmnb
kernel.msgmax
kernel.shmmax
kernel.shmall

step十、顯示eth0網卡的ip地址

[root@libin ~]# ifconfig eth0 | awk -F: '$1 ~ /inet addr.*/ {print $1,$2}' | awk '{print $1,$2,$3}'
inet addr 192.168.1.146

如上是awk的最基礎的用法,下篇還有awk的高級用法。

相關文章
相關標籤/搜索