1. 程式人生 > >awk速查手冊

awk速查手冊

連接數 txt -c 連接 查看 use 在一起 就是 net

awk速查手冊

score.txt

cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

netstat.txt

$cat netstat.txt
Proto Recv-Q Send-Q Local-Address          Foreign-Address             State
tcp        0      0 0.0.0.0:3306           0.0.0.0:*                   LISTEN
tcp        0      0 0.0.0.0:80             0.0.0.0:*                   LISTEN
tcp        0      0 127.0.0.1:9000         0.0.0.0:*                   LISTEN
tcp        0      0 coolshell.cn:80        124.205.5.146:18245         TIME_WAIT
tcp        0      0 coolshell.cn:80        61.140.101.185:37538        FIN_WAIT2
tcp        0      0 coolshell.cn:80        110.194.134.189:1032        ESTABLISHED
tcp        0      0 coolshell.cn:80        123.169.124.111:49809       ESTABLISHED
tcp        0      0 coolshell.cn:80        116.234.127.77:11502        FIN_WAIT2
tcp        0      0 coolshell.cn:80        123.169.124.111:49829       ESTABLISHED
tcp        0      0 coolshell.cn:80        183.60.215.36:36970         TIME_WAIT
tcp        0   4166 coolshell.cn:80        61.148.242.38:30901         ESTABLISHED
tcp        0      1 coolshell.cn:80        124.152.181.209:26825       FIN_WAIT1
tcp        0      0 coolshell.cn:80        110.194.134.189:4796        ESTABLISHED
tcp        0      0 coolshell.cn:80        183.60.212.163:51082        TIME_WAIT
tcp        0      1 coolshell.cn:80        208.115.113.92:50601        LAST_ACK
tcp        0      0 coolshell.cn:80        123.169.124.111:49840       ESTABLISHED
tcp        0      0 coolshell.cn:80        117.136.20.85:50025         FIN_WAIT2
tcp        0      0 :::22                  :::*                        LISTEN

1 輸出

1.1 普通輸出

輸出第1,4列

head -4 netstat.txt | awk '{print $1, $4}'

格式化輸出

head -4 netstat.txt | awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}'

1.2 內建變量

變量 說明
$0 當前記錄(這個變量中存放著整個行的內容)
$1~$n 當前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符 默認是空格或Tab
NF 當前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行號,從1開始,如果有多個文件話,這個值也是不斷累加中。
FNR 當前記錄數,與NR不同的是,這個值會是各個文件自己的行號
RS 輸入的記錄分隔符, 默認為換行符
OFS 輸出字段分隔符, 默認也是空格
ORS 輸出的記錄分隔符,默認為換行符
FILENAME 當前輸入文件的名字

輸出行號

head -4 netstat.txt | awk '{print NR, $3, $6}'

1.3 指定分隔符

輸出用戶名、uid和shell

awk -F: '{print $1, $3, $6}' OFS='\t' /etc/passwd
# 說明
# FS輸入的分隔符
# OFS輸出的分隔符

指定多個分隔符

-F '[:; ]+'
# +表示多個連在一起的分隔符算一個

2 應用場景

輸出第3列為0且第6列為LISTEN的行且輸出表頭

awk '$3==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt

2.1 字符串匹配

awk '$6 ~ /LISTEN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.t
awk '/LISTEN/' netstat.txt

# 說明
~表示模式開始
/FIN/表示模式

模式取反

awk '$6 !~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '!/WAIT/' netstat.txt

# 說明
!表示取反

2.2 拆分文件

awk 'NR!=1{print > $6}' netstat.txt
awk 'NR!=1{print $4,$5 > $6}' netstat.txt

# 說明
如果第6列有3種值a,b,c就會生成3個文件,每個文件是對應的行的數據

2.3 統計

計算所有C文件,CPP文件和H文件的文件大小總和

ls -l  *.cpp *.c *.h | awk '{sum+=$5} END {print sum}'

統計第6列connection狀態

awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt

統計每個用戶的進程的占了多少內存

ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'

2.4 使用腳本

統計學生的總分與平均分

cal.awk

$ cat cal.awk
#!/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
}

執行awk腳本

awk -f cal.awk score.txt

2.5 與環境變量交互

x=5
y=10
export y
echo $x $y
awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt

2.6 幾個花活

從file文件中找出長度大於80的行

awk 'length>80' file

按連接數查看客戶端IP

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

打印99乘法表

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

參考

  • The GNU Awk User’s Guide
  • AWK簡明教程

awk速查手冊