文件處理命令:awk

awk擅長於對數據進行分析並生成報告,簡單來講awk就是把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各類分析處理。正則表達式

使用方法:
awk '{pattern +action}' {filenames}express

[root@limt01 ~]# cat /etc/passwd|awk -F: '{ print $1 }'
root
bin
daemon
adm
lp
sync
。。。

其中 -F:爲指定分隔符爲:數組

 

awk的內建變量:
$0 當前記錄(這個變量中存放着整個行的內容)
$1~$n 當前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符默認是空格或Tab
NF 當前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行號,從1開始,若是有多個文件話,這個值也是不斷累加中。
FNR 當前記錄數,與NR不一樣的是,這個值會是各個文件本身的行號
RS 輸入的記錄分隔符,默認爲換行符
OFS 輸出字段分隔符,默認也是空格
ORS 輸出的記錄分隔符,默認爲換行符
FILENAME 當前輸入文件的名字bash

1 指定分隔符less

[root@limt01 tmp]# awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd
root 0 /root
bin 1 /bin
daemon 2 /sbin
adm 3 /var/adm
lp 4 /var/spool/lpd
sync 5 /sbin
shutdown 6 /sbin
halt 7 /sbin
mail 8 /var/spool/mail
operator 11 /root
games 12 /usr/games
ftp 14 /var/ftp
。。。

2 指定輸出分隔符(OFS="\t")ssh

[root@limt01 tmp]# awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
root    0       /root
bin     1       /bin
daemon  2       /sbin
adm     3       /var/adm
lp      4       /var/spool/lpd
sync    5       /sbin
shutdown        6       /sbin
halt    7       /sbin
mail    8       /var/spool/mail
operator        11      /root
games   12      /usr/games
ftp     14      /var/ftp
。。。

3 條件過濾輸出tcp

[root@limt01 tmp]# awk -F: '{ if( $1 ~ /root/ || $1 ~ /limt/) { print $1,$3,$6 } }' OFS="\t" /etc/passwd
root    0       /root
limt    1000    /home/limt
[root@limt01 tmp]# awk -F: '$1 ~ /root/ || $1 ~ /limt/  { print $1,$3,$6  }' OFS="\t" /etc/passwd
root    0       /root
limt    1000    /home/limt

4 重定向輸出到指定文件函數

[root@limt01 tmp]# awk 'NR!=1{print $0 > "/tmp/passwd" }' /etc/passwd
[root@limt01 tmp]# 
[root@limt01 tmp]# ls -lrt /tmp|tail
總用量 12
-rw-------. 1 root root    0 5月  20 21:36 yum.log
drwxr-xr-x. 2 root root   17 5月  20 21:43 hsperfdata_root
-rwx------. 1 root root  663 5月  20 21:48 ks-script-1AQjlc
drwx------. 3 root root   16 5月  22 08:44 systemd-private-HQgvzl
drwx------. 2 root root   23 5月  22 11:40 ssh-Hon4d3o0kn
-rw-r--r--. 1 root root 1184 5月  22 12:06 0
-rw-r--r--. 1 root root 1184 5月  22 13:24 passwd

5 -v帶入外部變量到awkspa

[root@limt01 tmp]# x=6
[root@limt01 tmp]# awk -v val=$x '{print val}' /etc/passwd|less
6
6
6
6

6 printf函數code

命令格式:
printf format,item1,item2……
使用要點:
1.format格式符必須使用
2.不會自動換行,須要手動添加行分隔符
3.format格式符中須要分別爲後面的每一個item指定一個格式符
格式符:都以%開頭,後跟一個字符
%c:顯示字符的ASCII碼;
%i,%d:顯示十進制整數;
%e,%E:科學計數法顯示數值;
%f:顯示浮點數;
%g,%G:以科學計數法格式或浮點數格式顯示數值;
%s:字符串;
%u:無符號整數;
%%:顯示%自身

[root@limt01 tmp]# netstat -an|awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}'
Active   Internet connections (servers           and                    established)   
Proto    Recv-Q   Send-Q   Local              Address                Foreign        
tcp      0        0        127.0.0.1:25       0.0.0.0:*              LISTEN         
tcp      0        0        0.0.0.0:22         0.0.0.0:*              LISTEN         
tcp      0        52       192.168.1.105:22   192.168.1.103:62831    ESTABLISHED    
tcp6     0        0        ::1:25             :::*                   LISTEN         
tcp6     0        0        :::22              :::*                   LISTEN         
udp      0        0        0.0.0.0:68         0.0.0.0:*                             
udp      0        0        192.168.1.105:123  0.0.0.0:*                             
udp      0        0        127.0.0.1:123      0.0.0.0:*                             
udp      0        0        0.0.0.0:123        0.0.0.0:*                             
udp      0        0        0.0.0.0:5353       0.0.0.0:*                             
udp      0        0        0.0.0.0:6480       0.0.0.0:*                             
udp      0        0        0.0.0.0:37782      0.0.0.0:*                          

awk中常見的模式類型:

1 /regular expression/:僅處理能被正則表達式匹配的

[root@limt01 tmp]# awk -F: '/^\<root\>/{print $1,$3}' /etc/passwd
root 0

2  relational expression:關係表達式,結果有真假之分,其結果爲非0或非空字符串時爲真,不然爲假

[root@limt01 tmp]# awk -F: '$3>=500{print $1,$3}' /etc/passwd
polkitd 999
libstoragemgmt 998
chrony 997
limt 1000

awk中經常使用的控制語句:

1 if else語句
if (condition) statement [ else statement ]
if (condition) {statements;} [ else {statements;} ]

[root@limt01 tmp]# awk -F: '{if ($3>=500) {print $1," is a common user"}else{print $1,"is a systemuser"}}' /etc/passwd
root is a systemuser
bin is a systemuser
daemon is a systemuser
adm is a systemuser
lp is a systemuser
sync is a systemuser
shutdown is a systemuser
。。。

2 while循環語句

語法格式:
while (condition) statement
while (condition) {statements}

[root@limt01 tmp]# awk -F: '$1~/root/{i=1;while(i<=NF){print $i;i+=2}}' /etc/passwd
root
0
root
/bin/bash

3 for循環語句

for (expr1;expr2;expr3) {statements}
for ( variable assignment(條件賦值);condition(循環執行); iteration process(變量修正)) { statement1, statement2, ...}

[root@limt01 tmp]# awk '{for(i=1;i<=NF;i+=2){if (length($i)>=6)print $i }}' /etc/issue
Kernel

4 switch語句

5 break and continue
break[n]:退出當前循環
continue[n]:提早結束本輪循環,直接進入下輪循環

6 next
提早結束對本行的處理而進入下一行的處理

 

數組:由於awk中數組的下標能夠是數字和字母,數組的下標一般被稱爲關鍵字(key)。值和關鍵字都存儲在內部的一張針對key/value應用hash的表格裏。因爲hash不是順序存儲,所以在顯示數組內容時會發現,它們並非按照你預料的順序顯示出來的。數組和變量同樣,都是在使用時自動建立的,awk也一樣會自動判斷其存儲的是數字仍是字符串。通常而言,awk中的數組用來從記錄中收集信息,能夠用於計算總和、統計單詞以及跟蹤模板被匹配的次數等等。

數組,關聯數組:array[index-expression]
要遍歷數組中的每個元素,須要使用以下特殊結構:
for (var in array) {for body}
其var會遍歷array的索引;而非元素值

[root@limt01 tmp]#  ss -tan |awk '!/State/{state[$1]++}END{for (i in state) {print i,state[i]}}'
LISTEN 4
ESTAB 1

使用腳本進行文本、數據處理:

#!/bin/awk -f
#運行前
BEGIN {
   math= 0
   english= 0
   computer= 0
 
   printf"NAME    NO.     MATH  ENGLISH  COMPUTER   TOTAL\n"
   printf"---------------------------------------------\n"
}
#運行中
{
   math+=$3
   english+=$4
   computer+=$5
   printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#運行後
END{
   printf"---------------------------------------------\n"
   printf "TOTAL:%10d %8d %8d \n", math, english, computer
   printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR,computer/NR
}
相關文章
相關標籤/搜索