awk基本應用回顧

一、AWK簡介:

AWK是一個文本報告生成器,它不僅是Linux中也是任何環境中現有的功能最強大的數據處理引擎之一,它具有編程及數據操作語言,提供了極其強大的功能:可以進行樣式裝入、流控制、數學運算符、過程控制語句甚至於內置的變量和函數。它具備了一個完整的語言所應具有的幾乎所有精美特性。它允許使用者創建簡短的程序,這些程序讀取輸入文件、爲數據排序、處理數據、對輸入執行計算以及生成報表等等功能。

在最初創造AWK時,其目的是用於文本處理,並且這種語言的基礎是,只要在輸入數據中有模式匹配,就執行一系列指令。AWK會掃描文件中的每一行,查找與命令行中所給定內容相匹配的內容,如果發現匹配內容,則進行下一個編程步驟。如果找不到匹配內容,則繼續處理下一行。

二、AWK語法:

awk [option]...'/PATTERN/{action}' FILE;語法中'/PATTERN/{action}'部分又被稱爲awk的腳本。

三、AWK基本應用示例:

1、打印文本文件的某個字段,默認分隔符爲空格:

[root@client2 html]# awk '{print $1}' /etc/fstab
#
#
#
#
#
#
#
/dev/mapper/vg0-root
UUID=3c74d332-e31d-4368-9e07-74479e1c4ad3
/dev/mapper/vg0-usr
/dev/mapper/vg0-var
/dev/mapper/vg0-swap
tmpfs
devpts
sysfs
proc

2、打印文本文件的多個字段:

[root@client2 html]# awk '{print $1,$2}' /etc/fstab 
 
# 
# /etc/fstab
# Created
# 
# Accessible
# See
# 
/dev/mapper/vg0-root /
UUID=3c74d332-e31d-4368-9e07-74479e1c4ad3 /boot
/dev/mapper/vg0-usr /usr
/dev/mapper/vg0-var /var
/dev/mapper/vg0-swap swap
tmpfs /dev/shm
devpts /dev/pts
sysfs /sys
proc /proc

3、打印所有字段,$0用於引用所有字段:

[root@client2 html]# awk '{print $0}' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Jul 28 19:06:01 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/vg0-root    /                       ext4    defaults        1 1
UUID=3c74d332-e31d-4368-9e07-74479e1c4ad3 /boot                   ext4    defaults        1 2
/dev/mapper/vg0-usr     /usr                    ext4    defaults        1 2
/dev/mapper/vg0-var     /var                    ext4    defaults        1 2
/dev/mapper/vg0-swap    swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

4、顯示指定的某行的某字段信息或打印連續的若干行:

[root@client1 ~]# awk 'NR==10{print $1}' /etc/fstab
UUID=3c74d332-e31d-4368-9e07-74479e1c4ad3
[root@node1 pam.d]# awk 'NR==8,NR==12' /etc/fstab
#
/dev/mapper/vg0-root    /                       ext4    defaults        1 1
UUID=fbb4629b-1279-4a2a-9f49-18faa0e5bece /boot                   ext4    defaults        1 2
/dev/mapper/vg0-usr     /usr                    ext4    defaults        1 2
/dev/mapper/vg0-var     /var                    ext4    defaults        1 2

5、NF(Number of Field) 打印每行有幾個字段,變量NF用於表示一行內的字段數,在AWK中引用變量時不需要加$,但是如果變量前加了$,如NF,那麼就是引用對應的字段的:

[root@client2 html]# awk '{print NF}' /etc/fstab
0
1
2
10
1
9
12
1
6
6
6
6
6
6
6
6
6

6、每行中最後一個字段的調用方式爲$NF:

[root@client2 html]# awk '{print $NF}' /etc/fstab
#
/etc/fstab
2014
#
'/dev/disk'
info
#
1
2
2
2
0
0
0
0
0

7、FS:Field Seperator,輸入分隔符,默認是空格:


8、OFS:輸出時的字段分隔符
9、語法表達式的/PATTERN/可以使用比較表達式,表達式用>,>=,<,<=,!=,==,~等比較字符來連接,比較的字符串與比較字符不需要用空格隔開,表達式也是正確的:

[root@client2 html]# awk -F: '$3 >= 500{print $1}' /etc/passwd
nfsnobody
[root@client2 html]# awk -F: '$3 < 500{print$1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
games
gopher
ftp
nobody
dbus
usbmuxd
vcsa
rtkit
rpc
avahi-autoipd
abrt
haldaemon
gdm
ntp
apache
saslauth
postfix
rpcuser
pulse
sshd
tcpdump
[root@client2 html]# awk -F: '$3 == 0{print $1}' /etc/passwd
root

10、模式匹配示例:AWK的模式與action字段之間不需要空格分開,比較表達式兩端與比較表達式字符之間不需要空格,而action與要處理的字段之間也不需要空格,整個表達式都連在一起也是正確的,只是屬於模式匹配的部分用//括起來,屬於action字段的要用{}括起來:

[root@client2 html]# awk -F: '$7~/bash$/{print$1}' /etc/passwd
root

11、顯示不相鄰的多個字段,$1$7連在一起,$1 $7用空格分隔,$1,$7用逗號分隔,注意看顯示的效果:

[root@client2 ~]# awk -F: '$7~/bash$/{print$1$7}' /etc/passwd
root/bin/bash
[root@client2 ~]# awk -F: '$7~/bash$/{print$1 $7}' /etc/passwd
root/bin/bash
[root@client2 ~]# awk -F: '$7~/bash$/{print$1,$7}' /etc/passwd
root /bin/bash

12、AWK中的action字段可以有多個,多個action字段要用{}括起來,比如,在輸出的字段前輸出表頭:

[root@client1 ~]# awk -F: 'BEGIN{print"username shell"}$7~/bash$/{print$1,$7}' /etc/passwd
username shell
root /bin/bash

下面這條語句是自己測試的語句,寫法是錯誤的,計算機在識別用戶輸入的命令時所做的語法分析是命令選項參數,參數中又有相對應的格式要求,比如模式和action,而下面語句中的action放在了前面,那麼計算機在識別整個字符串的時候就會認爲是一個命令加了一個要處理的參數,而我們要表達的模式匹配用來匹配某些行的效果就出不來了,這個字段要寫在action的前面,而不能在後面出現,它被計算機識別爲了其他的不能識別的字符。而如果要在action中使用多個命令,可以使用;來分隔多個action,模式也是一樣,也是用;來分隔開,但是總體上來說,模式和action要有前有後,不能混亂,如果在做模式匹配前,先對行進行一些處理操作,需要使用BEGIN模式,如果要在行處理之後做一些操作就要使用END模式,BEGIN模式是打破了常規的語法順序的,但是在程序的內部機制上被識別和匹配,而不是語法錯誤。

[root@client1 ~]# awk -F: '{print"username shell"}$7~/bash$/{print$1,$7}' /etc/passwd

13、顯示以bash結尾的且該行的第三字段數值小於500的行的第1和第3字段:

[root@client1 ~]# awk -F: '$7~/bash$/&&$3<500{print$1,$3}' /etc/passwd
root 0

14、顯示以bash結尾且該行第三個字段數值大於500的行的第1,第3,第7字段:

[root@client1 ~]# awk -F: '$7~/bash$/&&$3>500{print$1,$3,$7}' /etc/passwd

15、顯示第三字段數值小於500的行的第1,第3,第7字段,結果中可以看到只有root用戶是以bash結尾,所以之前的awk語句的寫法是正確的:

[root@client1 ~]# awk -F: '$3<500{print$1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
adm 3 /sbin/nologin
lp 4 /sbin/nologin
sync 5 /bin/sync
shutdown 6 /sbin/shutdown
halt 7 /sbin/halt
mail 8 /sbin/nologin
uucp 10 /sbin/nologin
operator 11 /sbin/nologin
games 12 /sbin/nologin
gopher 13 /sbin/nologin
ftp 14 /sbin/nologin
nobody 99 /sbin/nologin
dbus 81 /sbin/nologin
usbmuxd 113 /sbin/nologin
vcsa 69 /sbin/nologin
rtkit 499 /sbin/nologin
rpc 32 /sbin/nologin
avahi-autoipd 170 /sbin/nologin
abrt 173 /sbin/nologin
haldaemon 68 /sbin/nologin
gdm 42 /sbin/nologin
ntp 38 /sbin/nologin
apache 48 /sbin/nologin
saslauth 498 /sbin/nologin
postfix 89 /sbin/nologin
rpcuser 29 /sbin/nologin
pulse 497 /sbin/nologin
sshd 74 /sbin/nologin
tcpdump 72 /sbin/nologin

16、BEGIN模式示例,只有BEGIN模式字符開頭,後面從能用{}括起來action,後面從有可能再從頭查找PATTERN字串:

[root@client1 ~]# awk -F: 'BEGIN{print"username,shell"}$7~/bash$/{print$1,$7}' /etc/passwd
username,shell
root /bin/bash

要注意多個要顯示的字段或者字符串之間如果要用逗號分隔,那麼表示他們是不同的字段,如果未指定就要用默認的分隔符分隔開顯示,如果這些字段之間沒有用逗號分隔,那麼默認他們就被連起來顯示,在AWK中要表示多個連續的字段,沒有類似於其他表達方式的-等等連接符,只能是用其他的方式去遍歷需要顯示的多個字段。

[root@client1 ~]# awk -F: 'BEGIN{print"username,shell"}$7~/bash$/{print$1,$7}END{print"=====end====="}' /etc/passwd
username,shell
root /bin/bash
=====end=====

17、BEGIN模式:在{action}開始之前執行一次,製作表頭;

END模式:在{action}結束之後執行一次,製作表尾;

要從程序的運作機制角度去考慮語句的寫法會很容易記憶,寫語句時也不容易出錯。

而通常情況下BEGIN模式是用來指定輸入分隔符和輸出分隔符的,用法如下:

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

注意:BEGIN模式和END模式後面的模式字段要用{}括起來,裏面的分隔符要用“”引起來表示其爲前面變量的值,沒有該“”是語法錯誤,在awk中大寫的字符都是有特殊意義的,所以爲這個變量賦值的方式就決定了要這樣去用,否則就是錯誤,同樣,多個變量之間的賦值操作要用;隔開,否則也是語法錯誤,都要注意!













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章