Shell07--正則應用

1. 正則表達式概述

01. 什麼是正則表達式java

正則表達式regular expression, RE是一種字符模式,用於在查找過程當中匹配指定的字符。
02. 爲何要使用正則表達式?python

在工做中,咱們時刻面對着大量的日誌,程序,以及命令的輸出。迫切的須要過濾咱們須要的一部份內容,甚至是一個字符串。好比: 如今有一個上千行的文件,咱們僅須要其中包含"root"的行,怎麼辦? 此時就須要使用到正則表達式的規則來篩選想要的內容。

img
03. 正則表達式注意事項
1.正則表達式應用很是普遍,存在於各類語言中,例如:php,python,java等。2.正則表達式和通配符特殊字符是有本質區別的3.要想學好grep、sed、awk首先就要掌握正則表達式。4.注意正則神坑,中文符號。linux

2. 正則表達式規則

正則表達式          描述

\            轉義符,將特殊字符進行轉義,忽略其特殊意義

^            匹配行首,^是匹配字符串的開始

$            匹配行尾,$是匹配字符串的結尾

^           $表示空行.

(點)         匹配換行符以外的任意單個字符

[ ]         匹配包含在[字符]之中的任意一個字符

[^]         匹配[^]以外的任意一個字符

[a-z]       匹配[]中指定範圍內的任意一個字符

?           匹配其前面的字符1次或者0次+匹配其前面的字符1次或者屢次  匹配其前面的字符0次或者屢次**.**

*           表示全部( )匹配表達式,建立一個用於匹配的字符串

{n}         匹配以前的項n次,n是能夠爲0的正整數{n,}以前的項至少須要匹配n次

{n,m}       指定以前的項至少匹配n次,最多匹配m次,n<=m
|           或者


特定字符含義

[[:upper:]] 全部大寫字母

[[:lower:]] 全部小寫字母

[[:alpha:]] 全部字母

[[:digit:]] 全部數字

[[:alnum:]] 全部的字母和數字

[[:space:]] 空白字符,空白。

[[:punct:]] 全部標點符號

3. 正則表達式之GREP文本過濾

環境準備nginx

環境準備
[root@gjy ~]# cat test.txt
I am qiuzengjia teacher!
I teach linux.
test

I like badminton ball ,billiard ball and chinese chess!
my blog is http://www.oldboyedu.blog.com
our site is http://www.increase93.com
my qq num is 1176495252.
not 117666649555252.

正則git

#過濾以m開頭的行
[root@gjy ~]# grep "^m" test.txt
#過濾以m爲結尾的行
[root@gjy ~]# grep "m$" test.txt
#排除空行, 並打印行號
[root@gjy ~]# grep -vn "^$" test.txt
#匹配任意一個字符,不包括空行
[root@gjy ~]# grep "." test.txt
#匹配全部內容
[root@gjy ~]# grep ".*" test.txt
#過濾出以.爲結尾的行
[root@gjy ~]# grep "\.$" test.txt
#過濾出以m和n爲開頭的行
[root@gjy ~]# grep "^[mn]" test.txt
#過濾出文件中不是以m或n或o開始的行
[root@gjy ~]# egrep "^[^mno]" test.txt
[root@gjy ~]# egrep -v "^[mno]" test.txt
#過濾出空行,並顯示行號
[root@gjy ~]# grep -n "^$" test.txt
#把文件中每一個字母總共出現多少次統計出
[root@gjy ~]# grep -o "[a-Z]" test.txt |sort |uniq -c|sort -rh
#把文件中每一個單詞總共出現多少次統計出
[root@gjy ~]# egrep -o "[a-Z]+" test.txt |sort |uniq -c|sort -rh
#找出/etc/passwd文件中的兩位數或三位數的行;
[root@gjy ~]# grep -Ew "[0-9]{2,3}" /etc/passwd
#找出/proc/meminfo文件中,全部大寫或小寫s開頭的行;至少有三種實現方式;
[root@gjy ~]# grep "^[sS]" /proc/meminfo
[root@gjy ~]# grep -i "^s" /proc/meminfo
[root@gjy ~]# grep -E "^(s|S)" /proc/meminfo
#顯示當前系統上root、CentOS或user1用戶的相關信息;
[root@gjy ~]# grep -E "^(root|CentOS|user1)"
/etc/passwd

#找出/etc/init.d/functions文件中某單詞後跟一個小括號的行;
[root@gjy ~]# grep -E -o "^[_[:alnum:]]+\(\)" /etc/init.d/functions
#環境準備
[root@gjy ~]# cat id.txt
鄒 371481199403259478
莫 52020319810613433X
韓 46010619911113727A
榮 53012419750413543
榮 530124197504135438
阮 360702197902169951
任 6212231987082X5176
姜 370602198507189574
趙 BBB602198507189574
#找出正確的身份證號碼
[root@gjy ~]# egrep "[0-9]{17}[0-9X]" id.txt

4. 正則表達式之SED文本處理

Sed是一個流編輯器, 非交互式的編輯器,它一次處理一行內容. 處理時,把當前處理的行存儲在臨時緩衝區中,稱爲"模式空間"(pattern space)
接着用Sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。
文件內容並無改變,除非你使用重定向存儲輸出。
Sed是用來自動編輯一個或多個文件;簡化對文件的反覆操做;編寫轉換程序等。

01. Sed命令格式web

sed [options] 'command' file(s)
Sed正則使用與Grep同樣,Sed在文件中查找模式時也可使用正則表達式(RE)和各類元字符。
正則表達式是括在斜槓間的模式,用於查找和替換,如下是sed支持的元字符。
使用基本元字符集 ^, $, ., *, [], [^], < >, (), {} 使用擴展元字符集 ?, +, { }, |, ( ) 
使用擴展元字符的方式 + sed -r

02. Sed命令示例正則表達式

Sed對指定行進行操做,包括打印、刪除、修改、追加等。
Sed選項參數-e         
#容許多項編輯-n         
#取消默認的輸出-i         
#直接修改對應文件-r         
#支持擴展元字符Sed命令參數a         
#在當前行後添加一行或多行c         
#在當前行進行替換修改d         
#在當前行進行刪除操做i         
#在當前行以前插入文本p         
#打印匹配的行或指定行n         
#讀入下一輸入行,從下一條命令進行處理!         
#對所選行之外的全部行應用命令h         
#把模式空間裏的內容重定向到暫存緩衝區H         
#把模式空間裏的內容追加到暫存緩衝區g         
#取出暫存緩衝區的內容,將其複製到模式空間,覆蓋該處原有內容G       
#取出暫存緩衝區的內容,將其複製到模式空間,追加在原有內容後面

多重編輯選項 eshell

#先刪除行,而後管道給後面的sed進行替換
[root@gjy ~]# sed '1,9d' passwd |sed 's#root#gjy#g'
#使用-e進行屢次編輯修改操做
[root@gjy ~]# sed -e '1,9d' -e 's#root#gjy#g' passwd

打印命令pexpress

g#打印匹配halt的行
[root@gjy ~]# sed -n '/halt/p' passwd
halt:x:7:0:halt:/sbin:/sbin/halt
#打印第二行的內容
[root@gjy ~]# sed -n '2p' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
#打印最後一行
[root@gjy ~]# sed -n '$p' passwd
**追加命令a**

#給30行添加配置 \t tab鍵(須要轉義) \n 換行符
[root@gjy ~]# sed -i '30a listen 80;' passwd

追加命令a

給30行添加配置 \t tab鍵(須要轉義) \n 換行符
[root@gjy ~]# sed -i '30a listen 80;' passwd

修改命令c

#指定某行進行內容替換
[root@gjy ~]# sed -i '7c SELINUX=Disabled' /etc/selinux/config
#正則匹配對應內容, 而後進行替換
sed -i '/^SELINUX=/cSELINUX=Disabled' /etc/selinux/config
#非交互式修改指定的配置文件
[root@gjy ~]# sed -i '/UseDNS/cUseDNS no' /etc/ssh/sshd_config
[root@gjy ~]# sed -i '/GSSAPIAuthentication/c#GSSAPIAuthentication no' /etc/ssh/sshd_config

刪除命令d

#指定刪除第三行, 但不會改變文件內容
[root@gjy ~]# sed '3d' passwd
[root@gjy ~]# sed '3{d}' passwd
#從第三行刪除到最後一行
[root@gjy ~]# sed '3,$d' passwd
#刪除最後一行
[root@gjy ~]# sed '$d' passwd
#刪除全部的行
[root@gjy ~]# sed '1,$d' passwd
#匹配字符串進行該行刪除
[root@gjy ~]# sed '/mail/d' passwd

插入命令i

#在文件的某一行上面添加內容
[root@gjy ~]# sed -i '30i listen 80;' passwd

寫文件命令w

#將匹配到的行寫入到新文件中
[root@gjy ~]# sed -n '/root/w newfile' passwd
#將passwd文件的第二行寫入到newfile中
[root@gjy ~]# sed -n '2w newfile' passwd

獲取下一行命令n

#匹配root的行, 刪除root行的下一列
[root@gjy ~]# sed '/root/{n;d}' passwd
#替換匹配root行的下一列
[root@gjy ~]# sed '/root/{n; s/bin/test/}' passwd

暫存和取用命令h H g G

#將第一行的寫入到暫存區, 替換最後一行的內容
[root@gjy ~]# sed '1h;$g' /etc/hosts
#將第一行的寫入到暫存區, 在最後一行調用暫存區的內容
[root@gjy ~]# sed '1h;$G' /etc/hosts
#將第一行的內容刪除但保留至暫存區, 在最後一行調用暫存區內容追加至於尾部
[root@gjy ~]# sed '1{h;d};$G' /etc/hosts
#將第一行的內容寫入至暫存區, 從第二行開始進行重定向替換
[root@gjy ~]# sed '1h;2,$g' /etc/hosts
#將第一行重定向至暫存區, 2-3行追加至暫存區, 最後追加調用暫存區的內容
[root@gjy ~]# sed '1h; 2,3H; $G' /etc/hosts
[root@gjy ~]# sed '1,3H; $G' /etc/hosts

反向選擇命令!

#除了第三行,其餘所有刪除
[root@gjy ~]# sed '3!d' /etc/hosts

03. Sed匹配替換

s #替換命令標誌
g #行內全局替換
i #忽略替換大小寫

替換命令s

#替換每行出現的第一個root
[root@gjy ~]# sed 's/root/alice/' passwd
#替換以root開頭的行
[root@gjy ~]# sed 's/^root/alice/' passwd
#查找匹配到的行, 在匹配的行後面添加內容
[root@gjy ~]# sed 's/[0-9][0-9]$/& new/' passwd
#匹配包含有root的行進行替換
[root@gjy ~]# sed 's/root/alice/g' passwd
#匹配包含有root的行進行替換,忽略大小寫
[root@gjy ~]# sed 's/root/alice/gi' /etc/passwd
#後向引用
[root@gjy ~]# sed -r 's#(roo)#\1-alice#g' passwd
[root@gjy ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*et) (.*) (net.*$)#\2#g'
#示例
[root@web ~]# vim a.txt
/etc/abc/456
etc
#刪除文本中的內容,需加轉義
[root@gjy ~]# sed '/\/etc\/abc\/456/d' a.txt
#若是碰到/符號, 建議使用#符替換
[root@gjy ~]# sed 's#/etc/abc/456#/dev/null#g' a.txt
[root@gjy ~]# sed 's@/etc/abc/456@/dev/null@' a.txt

刪除文件

#刪除配置文件中#號開頭的註釋行, 若是碰到tab或空格是沒法刪除
[root@gjy ~]# sed '/^#/d' file
#刪除配置文件中含有tab鍵的註釋行
[root@gjy ~]# sed -r '/^[ \t]*#/d' file
#刪除無內容空行
[root@gjy ~]# sed -r '/^[ \t]*$/d' file
#刪除註釋行及空行
[root@gjy ~]# sed -r '/^[ \t]*#/d; /^[ \t]*$/d' /etc/vsftpd/vsftpd.conf
[root@gjy ~]# sed -r '/^[ \t]*#|^[ \t]*$/d' /etc/vsftpd/vsftpd.conf
[root@gjy ~]# sed -r '/^[ \t]*($|#)/d' /etc/vsftpd/vsftpd.conf

給文件行添加註釋

#將第二行到第六行加上註釋信息
[root@gjy ~]# sed '2,6s/^/#/' passwd
#將第二行到第六行最前面添加#註釋符
[root@gjy ~]# sed -r '2,6s/.*/#&/' passwd
#添加#註釋符
[root@gjy ~]# sed -r '3,$ s/^#*/#/' passwd
[root@gjy ~]# sed -r '3,$ s/^/#/' passwd
[root@gjy ~]# sed -r '30,50s/^[ \t]*#*/#/' /etc/nginx.conf
[root@gjy ~]# sed -r '2,8s/^[ \t#]*/#/' /etc/nginx.conf

5. 正則表達式之AWK文本處理

01. Awk基本介紹

什麼是Awk?

awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。
awk數據能夠來自標準輸入、一個或多個文件,或其它命令的輸出。
awk一般是配合腳本進行使用, 是一個強大的文本處理工具。

awk 的處理文本和數據的方式以下:

1.進行逐行掃描文件, 從第一行到最後一行
2.尋找匹配的特定模式的行,在行上進行操做
3.若是沒有指定處理動做,則把匹配的行顯示到標準輸出
4.若是沒有指定模式,則全部被操做的行都被處理

Awk語法格式。

awk 的語法格式awk [options] 'commands' filenames

img

#命令 command行處理前     行處理     行處理後
BEGIN{}     {}          END{}
#BEGIN發生在讀文件以前
[root@gjy ~]# awk 'BEGIN{print 1/2}'
0.5
#BEGIN在行處理前, 修改字段分隔符
[root@gjy ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd
#BEGIN在行處理前, 修改字段讀入和輸出分隔符
[root@gjy ~]# awk 'BEGIN{FS=":";OFS="---"} {print $1,$2}' /etc/passwd
#示例
[root@gjy ~]# awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}' /etc/hosts
0.5
ok
ok
ok
Game Over

Awk工做原理

awk -F: '{print $1,$3}' /etc/passwd
1.awk將文件中的每一行做爲輸入, 並將每一行賦給內部變量 $0 , 以換行符結束
2.awk開始進行字段分解,每一個字段存儲在已編號的變量中,從$1開始[默認空格分割]
3.awk默認字段分隔符是由內部FS變量來肯定, 可使用-F修訂
4.awk行處理時使用了print數打印分割後的字段
5.awk在打印後的字段加上空格,由於$1,$3之間有一個逗號。逗號被映射至OFS內部變量中,稱爲輸出字段分隔符,OFS 默認爲空格.
6.awk輸出以後,將從文件中獲取另外一行,並將其存儲在$0中,覆蓋原來的內容,而後將新的字符串分隔成字段並進行處理。該過程將持續到全部行處理完畢.

Awk命令格式

#示例1, 匹配 awk 'pattern' filename
[root@gjy ~]# awk '/root/' /etc/passwd
#示例2, 處理動做 awk '{action}' filename
[root@gjy ~]# awk -F: '{print $1}' /etc/passwd
#示例3, 匹配+處理動做 awk 'pattern {action}' filename
[root@gjy ~]# awk -F ':' '/root/ {print $1,$3}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd
#示例4, 判斷大於多少則輸出什麼內容 command |awk 'pattern {action}'
[root@gjy ~]# df |awk '/\/$/ {if ($3>50000) print $4}'

02. Awk分隔符

e在學習awk的過程當中,咱們先來快速的熟悉下awk分隔符的做用。
請事先準備以下數據文件:
[root@gjy ~]# cat awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65

Awk指定多個分隔符,Awk默認以空白行做爲分隔符

#1.如何查看文件中的第一列
[root@gjy ~]# awk '{print $1}' awk_file.txt
ll
kk
hh
jj
mm
#2.若是有的文件不是以空格爲分隔符怎麼辦?好比/etc/passwdh
[root@gjy ~]# awk -F: '{print $7}' passwd |tail -1
/bin/bash
#3.如何指定多個分隔符,好比想獲取第二列的內容?
[root@gjy ~]# cat awk_file.txt
ll:1990 50 51 61
kk:1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
#以冒號或空格爲分隔符
[root@gjy ~]# awk -F '[: ]' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994
#4.指定多個分隔符
[root@gjy ~]# cat awk_file.txt
ll::1990 50 51 61
kk:1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
#[: ]+連續的多個冒號當一個分隔符,連續的多個空格當一個分隔符,連續空格和冒號也當作一個字符來處理
[root@gjy ~]# awk -F '[: ]+' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994

03. Awk內部變量

要想了解awk的一些內部變量須要先準備以下數據文件。
[root@gjy ~]# cat awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65

3.1 Awk內置變量NF,保存每行的最後一列

#1.經過print打印,NF和$NF,你發現了什麼?
[root@gjy ~]# awk '{print NF,$NF}' awk_file.txt
5 61
5 62
5 63
5 64
5 65
#若是將第五行的55置爲空,那麼該如何在獲取最後一列的數字?
[root@gjy ~]# awk '{print $5}' awk_file.txt
61
62
63
64
#最後一列爲空,爲何?
#使用$NF爲何就能成功?(由於NF變量保存的是每一行的最後一列)
[root@gjy ~]# awk '{print $NF}' awk_file.txt
61
62
63
64
65
#2.若是一個文件很長,靠數列數須要很長的時間,那如何快速打印倒數第二列?
[root@gjy ~]# awk '{print $(NF-1)}' awk_file.txt
51
52
53
54
90

3.2 Awk內置變量$0,完整的當前文件的內容

[root@gjy ~]# awk '{print $0}' awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 65

3.3 Awk內置變量NR,表示記錄行號

#1.使用print打印NR,會發現NR會記錄每行文件的行號
[root@gjy ~]# awk '{print NR,$0}' awk_file.txt
1 ll 1990 50 51 61
2 kk 1991 60 52 62
3 hh 1992 70 53 63
4 jj 1993 80 54 64
5 mm 1994 90 65
#2.那若是咱們想打印第二行到第三行的內容怎麼辦?
[root@gjy ~]# awk 'NR>1&&NR<4 {print NR,$0}' awk_file.txt
2 kk 1991 60 52 62
3 hh 1992 70 53 63
#2.那若是隻想打印第三行,該怎麼辦?
[root@gjy ~]# awk 'NR==3 {print NR,$0}' awk_file.txt
3 hh 1992 70 53 63
#3.那若是既想打印第三行,又想打印第一列?
[root@gjy ~]# awk 'NR==3 {print NR,$1}' awk_file.txt
3 hh

3.4 Awk內置變量FNR,記錄輸入每一個文件的編號

[root@gjy ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts

3.5 Awk內置變量,FS指定字段分割符, 默認是空格

#以冒號做爲字段分隔符
[root@gjy ~]# awk -F: '/root/{print $1,$3}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
[root@gjy ~]# awk -v FS=: '{print $1,$3}' /etc/passwd
#以空格冒號tab做爲字段分割
[root@Shell ~]# awk -F '[ :\t]' '{print $1,$2,$3}' /etc/passwd

3.6 Awk內置變量OFS,指定輸出字段分隔符

#,逗號映射爲OFS, 初始狀況下OFS變量是空格
[root@gjy ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd
[root@gjy ~]# awk -v FS=":" -v OFS="+++" '/^root/{print $1,$2}' /etc/passwd

3.7 Awk內置變量RS,輸入記錄分隔符,默認爲換行符(瞭解)

[root@gjy ~]# cat test.txt
oldboy/oldgirl/olddog
[root@gjy ~]# awk 'BEGIN{RS="/"}{print $0}' test.txt
oldboy
oldgirl
olddog

3.8 Awk內置變量ORS,將文件每一行合併爲一行,以空格爲分割(瞭解)

[root@gjy ~]# awk 'BEGIN{ORS="#"} {print $0}' /etc/hosts

3.9 Print格式化輸出函數

[root@gjy ~]# date|awk '{print "本月是:"$2 "\n今年是:"$NF}'
[root@gjy ~]# awk -F: '{print "用戶是:" $1 "\t 用戶uid: " $3 "\t 用戶gid:" $4}' /etc/passwd
#printf函數(瞭解)
[root@gjy ~]# awk -F: '{printf "%-15s %-10s %-15s\n", $1, $2, $3}' /etc/passwd
#%s字符類型,%d數值類型,佔15字符, -表示左對齊,默認是右對齊,printf默認不會在行尾自動換行,加\n

04. Awk模式動做

awk語句都由模式和動做組成。
模式部分決定動做語句什麼時候觸發及觸發事件。
若是省略模式部分,動做將時刻保持執行狀態。模式能夠是條件語句或複合語句或正則表達式。

4.1 正則表達式

#匹配記錄(整行)
[root@gjy ~]# awk '/^root/' /etc/passwd
[root@gjy ~]# awk '$0 ~/^root/' /etc/passwd
#匹配字段:匹配操做符(~ !~)
[root@gjy ~]# awk '!/^root/' /etc/passwd
[root@gjy ~]# awk '$0 !~ /^root/' /etc/passwd

4.2 比較表達式

比較表達式採用對文本進行比較,只有當條件爲真,才執行指定的動做。比較表達式使用關係運算符,用於比較數字與字符串。
關係運算符

運算符含義示例
<         小於               x<y
<=       小於等於        x<=y
==       等於               x==y
!=        不等於            x!=y 
>=       大於等於        x>=y
>         大於               x>y
#uid爲0的列出來
[root@gjy ~]# awk -F ":" '$3==0' /etc/passwd
#uid小於10的所有列出來
[root@gjy ~]# awk -F: '$3 < 10' /etc/passwd
#用戶登錄的shell等於/bin/bash
[root@gjy ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd
#第一列爲alice的列出來
[root@gjy ~]# awk -F: '$1 == "alice" ' /etc/passwd
#爲alice的用戶列出來
[root@gjy ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd
[root@gjy ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd
#磁盤使用率大於多少則,則打印可用的值
[root@gjy ~]# df |awk '/\/$/'|awk '$3>1000000 {print $4}'

4.3 條件表達式

[root@gjy ~]# awk -F: '$3>300 {print $0}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3>300) print $0}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3>5555){print $3} else {print $1}}' /etc/passwd

4.4 運算表達式

[root@gjy ~]# awk -F: '$3 * 10 > 500000' /etc/passwd
[root@gjy ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>50000) {print $1,$3} } END {print "打印ok"}' /etc/passwd
[root@gjy ~]# awk -F: '/sshd/{print $3}' passwd
74
[root@gjy ~]# awk -F: '/sshd/{print $3 + 10 }' passwd
84
[root@gjy ~]# awk -F: '/sshd/{print $3 + 10.56 }' passwd
84.56
[root@gjy ~]# awk -F: '/sshd/{print $3 - 10 }' passwd
64
[root@gjy ~]# awk -F: '/sshd/{print $3 * 10 }' passwd
740
[root@gjy ~]# awk -F: '/sshd/{print $3 / 10 }' passwd
7.4
[root@gjy ~]# awk -F: '/sshd/{print $3 % 10 }' passwd
4[root@gjy ~]# awk 'BEGIN{print 85 + 10 }'
95
[root@gjy ~]# awk 'BEGIN{print 85 - 10 }'
75
[root@gjy ~]# awk 'BEGIN{print 85 * 10 }'
850
[root@gjy ~]# awk 'BEGIN{print 85 / 10 }'
8.5
[root@gjy ~]# awk 'BEGIN{print 85 % 10 }'
5
[root@gjy ~]# awk 'BEGIN{print 85 ^ 10 }'
19687440434072264704

4.5 邏輯操做符和複合模式

&& 邏輯與
|| 邏輯或

! 邏輯非

#匹配用戶名爲root而且打印uid小於15的行
[root@gjy ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd
#匹配用戶名爲root或uid大於5000
[root@gjy ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd
#匹配不是以root開頭的行
[root@gjy ~]# awk '!/^root/' /etc/passwd

Awk示例1:解釋其下列命令的含義

# awk '/west/' datafile
# awk '/^north/' datafile
# awk '$3 ~ /^north/' datafile
# awk '/^(no|so)/' datafile
# awk '{print $3,$2}' datafile
# awk '{print $3 $2}' datafile
# awk '{print $0}' datafile
# awk '{print "Number of fields: "NF}' datafile
# awk '/northeast/{print $3,$2}' datafile
# awk '/^[ns]/{print $1}' datafile
# awk '$5 ~ /\. [7-9]+/' datafile
# awk '$2 !~ /E/{print $1,$2}' datafile
# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile
# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile
# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile
# awk '/Tj/{print $0}' datafile
# awk -F: '{print "Number of fields: "NF}' /etc/passwd
# awk -F"[ :]" '{print NF}' /etc/passwd

Awk示例2

[root@gjy ~]# cat b.txt
web qiudao:is a:good boy!
[root@gjy ~]# awk '{print NF}' b.txt
4
[root@gjy ~]# awk -F ':' '{print NF}' b.txt
3
[root@gjy ~]# awk -F"[ :]" '{print NF}' b.txt
6

05. Awk條件判斷

if語句格式:{ if(表達式){語句;語句;... }}
#打印當前管理員用戶名稱
[root@gjy ~]# awk -F: '{ if($3==0){print $1 "is adminisitrator"} }' /etc/passwd
#統計系統用戶數量
65
[root@gjy ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd
#統計普通用戶數量
[root@gjy ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd
if...else語句格式:{if(表達式){語句;語句;... }else{語句;語句;...}}[root@gjy ~]# awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3==0){count++} else{i++}} END{print " 管理員個數: "count ; print " 系統用戶數: "i}' /etc/passwd

if...else if...else語句格式:{if(表達式 1){語句;語句;... }else if(表達式 2){語句;語句;. .. }else{語句;語句;... }}
[root@gjy ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print i;print j;print k}' /etc/passwd
[root@gjy ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print "管理員個數"i; print "系統用戶個數" j; print "系統用戶個數" k }' /etc/passwd

06. Awk循環語句

while循環
[root@gjy ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }'
[root@gjy ~]# awk -F: '{i=1; while(i<=NF){print i; i++}}' /etc/passwd
[root@gjy ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd
[root@gjy ~]# cat b.txt
111 222
333 444 555
666 777 888 999
[root@gjy ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt
for循環#C 風格 for
[root@gjy ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }'
#將每行打印 10 次
[root@gjy ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd

07. Awk數組概述
將須要統計的某個字段做爲數組的索引,而後對索引進行遍歷

7.1 統計/etc/passwd 中各類類型 shell 的數量

[root@gjy ~]# awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd

7.2 網站訪問狀態統計 <當前時實狀態ss>

[root@gjy ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}'

7.3 統計當前的tcp的11種狀態數量<當前時實狀態 netstat,ss>

[root@gjy ~]# ss -ant|sed '1d'|awk '{status[$1]++} END {for(i in status){print i,status[i]}}'

08. Awk數組案例

Nginx日誌分析,日誌格式以下:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';52.55.21.59 - - [22/Nova/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https:#www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"

8.1 統計2018年11月22日,當天的PV量

[root@gjy ~]# grep "22/Nov/2018" access.log |wc -l
[root@gjy ~]# awk "/22\/Nov\/2018/" access.log |wc -l
[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' access.log
#統計11-12點的pv量
[root@gjy ~]# awk '$4>="[22/Nov/2018:11:00:00" && $4<="[22/Nov/2018:12:00:00 {print $0}"' access.log |wc -l

8.2 統計2018年11月22日,一天內訪問最多的10個IP

[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){ print ips[i],i}}' access.log |sort -rn|head
#統計11-12點訪問次數最多的10個IP
[root@gjy ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00"' access.log |awk '{ips[$1]++} END {for(i in ips){print ips[i],i}}'|sort -rn|head

8.3 統計2018年11月22日,訪問大於100次的IP

[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){if(ips[i]>100){print i,ips[i]}}}' access.log

8.4 統計2018年11月22日,訪問最多的10個頁面($request top 10)

[root@gjy ~]# awk '/22\/Nov\/2018/ {request[$7]++} END {for(i in request){print request[i],i}}' access.log |sort -rn|head

8.5 統計2018年11月22日,每一個URL訪問內容總大小($bodybytessent)

[root@gjy ~]# awk '/22\/Nov\/2018/{size[$7]+=$10} END {for(i in size){print size[i],i}}' access.log |sort -rn|head

8.6 統計2018年11月22日,每一個IP訪問狀態碼數量($status)

[root@gjy ~]# awk '{ip_code[$1 " " $9]++} END {for(i in ip_code){print ip_code[i],i}}' access.log|sort -rn|head

8.7 統計2018年11月22日,訪問狀態碼爲404及出現的次數($status)

[root@gjy ~]# grep "404" access.log |wc -l
[root@gjy ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.8 統計2018年11月22日,8:30-9:00訪問狀態碼是404

[root@gjy ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log
[root@gjy ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.9 統計2018年11月22日,各類狀態碼數量

[root@gjy ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.10 統計日誌中全部URL訪問的次數及訪問響應的內容總大小

[root@gjy ~]# awk '{request[$7]++;size[$7]+=$10} END {for(i in request){print request[i],i,size[i]}}' access.log |sort -rn|head
相關文章
相關標籤/搜索