AWK 不再難:案例驅動學習,讓你成為數據處理高手
在數據處理領域,AWK 是一個強大而靈活的工具,盡管很多人對它感到陌生或畏懼。本文將通過實際案例,幫助你逐步掌握 AWK 的基本用法,讓你在數據處理方面游刃有余。
案例1:使用awk提取文本
1.問題
本案例旨在通過運用awk工具實現以下目標:
- 熟練掌握awk工具的基礎操作與語法。
- 從系統(tǒng)中提取關鍵信息,包括但不限于網絡接口的流量數據、根文件系統(tǒng)的剩余空間容量,以及記錄嘗試通過SSH協(xié)議進行遠程連接但未成功的IP地址列表。
- 對/etc/passwd文件中的內容進行處理,以結構化格式展示用戶的登錄名(用戶名)、用戶標識號(UID)及其主目錄路徑等信息。
2.解答
AWK是一種文本處理工具,能夠讀取輸入行并根據指定模式進行操作。它的基本語法如下:
awk 'pattern { action }' filename
在編輯指令中,print 是最常用的一個。當需要執(zhí)行多條編輯指令時,可以使用分號進行分隔。此外,Awk 在過濾數據時支持僅輸出特定列的數據,例如第二列或第五列等。在處理文本的過程中,如果沒有明確指定字段分隔符,則默認情況下 awk 會將空格和制表符視為字段之間的分隔標志。
(1) 結合管道過濾獲取每個分區(qū)的剩余容量信息
(2) 選項-F指定分隔符
輸出passwd文件中以分號分隔的第1、7個字段,顯示的不同字段之間以逗號隔開,操作如下:
為了提取passwd文件中以分號分隔的第一和第七個字段,可以執(zhí)行以下命令:
awk -F : '{print $1,$7}' /etc/passwd
執(zhí)行上述命令后,輸出如下圖的結果
awk常用內置變量:
- $1文本的第1列
- $2文件的第2列
- $3文件的第3列,依此類推
- NR 文件當前行的行號
- NF文件當前行的列數(有幾列)
利用awk提取本機的網絡流量、根分區(qū)剩余容量、獲取遠程失敗的IP地址。
通過ifconfig eth0查看網卡信息,其中包括網卡流量:
RX為接收的數據量,TX為發(fā)送的數據量。packets以數據包的數量為單位,bytes以字節(jié)為單位,為了直觀把字節(jié)轉成兆。
root@pve:~# ifconfig vmbr0 | awk '/RX packets/{print $5/1024/1024 " MB"}'
180.912 MB
root@pve:~# ifconfig vmbr0 | awk '/TX packets/{print $5/1024/1024 " MB"}'
2491.94 MB
提取根分區(qū)剩余容量,通過df命令查看根分區(qū)的使用情況,其中包括剩余容量:
root@pve:~# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/pve-root 68G 27G 38G 42% /
輸出上述結果中最后一行的第4列:
root@pve:~# df -h / | tail -1 | awk '{print $4}'
38G
根據/var/log/auth.log日志文件,通過正則方式進行過濾遠程連接密碼失敗的IP地址,并統(tǒng)計,執(zhí)行如下命令:
awk '/Failed/{match($0, /([0-9]{1,3}\.){3}[0-9]{1,3}/, arr); if (arr[0]) print arr[0]}' \
/var/log/auth.log | sort | uniq -c
執(zhí)行上述命令后,輸出如下結果:
案例2:awk處理條件
1.問題
在本案例中,需運用awk工具執(zhí)行以下過濾任務。請?zhí)貏e注意awk處理條件的設定:
- 提取并展示用戶ID(UID)位于1至1000范圍內的所有用戶的詳細信息。
- 從/etc/hosts文件中篩選出以127或192開頭的所有記錄行。
- 構建一個列表,包含100以內所有是7的倍數或者數字本身含有7的所有整數。
2.解答
(1) 使用正則設置條件
輸出其中以bash結尾的完整記錄:
root@didiplus:~# awk -F: '/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
請篩選出那些登錄Shell字段(即第七個字段)不以"nologin"結尾的用戶記錄,并展示這些用戶的用戶名及其對應的登錄Shell信息。具體來說,可以采用對第七個字段進行反向匹配(!~)的方式來實現這一需求。
root@didiplus:~# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd
root /bin/bash
sync /bin/sync
pollinate /bin/false
tss /bin/false
lxd /bin/false
1panel /bin/sh
(2) 使用數值/字符串比較設置條件
在Shell腳本中,常用的比較運算符包括:
整數比較:
- -lt:小于
- -le:小于或等于
- -eq:等于
- -ne:不等于
- -gt:大于
- -ge:大于或等于
字符串比較:
- ==:等于
- !=:不等于
- >:大于
- <:小于
- >=:大于或等于
- <=:小于或等于
這些運算符用于條件判斷,以實現邏輯控制和流程管理。
輸出第3行(行號NR等于3)的用戶記錄:
root@didiplus:~# awk -F: 'NR==3{print}' /etc/passwd
bin:x:2:2:bin:/bin:/usr/sbin/nologin
輸出賬戶UID大于等于1000的賬戶名稱和UID信息:
root@didiplus:~# awk -F: '$3>=1000{print $1,$3}' /etc/passwd
nobody 65534
1panel 1000
(3) 邏輯測試條件
輸出賬戶UID大于10并且小于20的賬戶信息:
root@didiplus:~# awk -F: '$3>10 && $3<20' /etc/passwd
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
(4) 數學運算
統(tǒng)計3的倍數的數量
root@didiplus:~# seq 200 | awk '$1%3==0{i++} END{print i}'
66
(5) 完成任務要求的awk過濾操
列出UID間于1~1000的用戶詳細信息:
awk -F: '$3>=1 && $3<=1000' /etc/passwd
執(zhí)行上述命令后,輸出如下結果:
輸出 /etc/hosts 映射文件內以127或者192開頭的記錄:
root@didiplus:~# awk -F: '/^(127|192)/' /etc/hosts
127.0.0.1 localhost
127.0.1.1 Aliyun
列出100以內整數中7的倍數或是含7的數:
seq 100 | awk '$1%7==0||$1~/7/{print}'
$1~/7/:這個條件使用正則表達式檢查數字中是否包含字符“7”。如果是,條件為真。
案例3:awk綜合腳本應用
1.問題
本案例要求開發(fā)一個名為 getupwd-awk.sh 的腳本,以滿足以下功能需求:
- 識別并篩選出使用 bash 作為登錄 Shell 的本地用戶。
- 對于這些選定的用戶,提取他們在 /etc/shadow 文件中的密碼記錄。
- 將結果格式化為“用戶名 --> 密碼記錄”的形式,并按行保存至 getupwd.log 文件中。最終輸出格式應如下圖所示。
2.解答
根據需求編寫getupwd-awk.sh,內容如下:
#!/bin/bash
# 定義輸出文件
output_file="getupwd.log"
# 清空輸出文件
> "$output_file"
# 獲取使用 bash 作為登錄 Shell 的本地用戶
awk -F: '$7 == "/bin/bash" {print $1}' /etc/passwd | while read -r user; do
# 獲取該用戶的密碼記錄
passwd_record=$(sudo grep "^$user:" /etc/shadow)
# 如果找到了密碼記錄,格式化并輸出
if [ -n "$passwd_record" ]; then
echo "$user --> $passwd_record" >> "$output_file"
fi
done
echo "密碼記錄已保存到 $output_file"
案例4:awk擴展應用
1.問題
在解析Web日志文件時,首列顯示了客戶端的IP地址。由于存在大量重復的IP地址,僅用awk提取這些信息還不夠,還需要統(tǒng)計每個IP地址出現的次數并對結果排序。
為此,可以使用awk創(chuàng)建一個關聯數組,以IP地址為鍵值。每當遇到相同的IP地址時,對應的計數器加一,從而計算出每個IP地址的總出現次數。
對于排序結果,建議使用sort命令配合不同的參數來滿足需求。例如,使用-n選項按數值升序排列,-r選項實現降序排列,而-k則允許根據特定字段排序。這一系列步驟有助于從原始日志中有效提取并展示有用的信息。
2.解答
統(tǒng)計Web訪問量排名:
(1) 提取IP地址及訪問量:
awk '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' \
/opt/1panel/apps/openresty/openresty/www/sites/didiplus.kwpmp.cn/log/access.log
執(zhí)行上述命令后,輸出如下結果:
(2) 對上一步的結果根據訪問量排名:
awk '{ip[$1]++} END{for(i in ip) {print i,ip[i]}}' \
/opt/1panel/apps/openresty/openresty/www/sites/didiplus.kwpmp.cn/log/access.log \
sort -nr -k 2
命令 sort -nr -k 2 的含義如下:
- **-n**:按照數值大小進行排序,而不是字典順序。
- **-r**:進行逆序排序,從大到小。
- **-k 2**:指定根據第二列進行排序
總結
AWK 是一個靈活且強大的工具,通過以上案例,你可以看到它在實際數據處理中所帶來的便利。無論是提取信息、計算統(tǒng)計,還是格式化輸出,AWK 都能輕松應對。通過案例驅動的學習方法,你會發(fā)現 AWK 不再難,反而是提升數據處理能力的得力助手。