shell 使用awk提取文本

1.使用awk提取文本
問題
本案例要求使用awk工具完成下列過濾任務:
練習awk工具的基本用法
提取本機的IP地址、根分區使用率
格式化輸出/etc/passwd文件中的用戶名、UID、宿主目錄信息
格式化輸出passwd文件內容時,要求第一行爲列表標題,最後一行提示一共已處理文本的總行數,如圖-1所示。
在這裏插入圖片描述
圖-1
步驟
實現此案例需要按照如下步驟進行。
步驟一:awk文本過濾的基本用法
1)基本操作方法
格式:awk [選項] ‘[條件]{編輯指令}’ 文件
其中,print 是最常用的編輯指令;若有多條編輯指令,可用分號分隔。
處理文本時,若未指定分隔符,則默認將空格、製表符等作爲分隔符。
直接過濾文件內容:
[root@svr5 ~]# cat /etc/rc.local //文件的完整內容
#!/bin/sh

This script will be executed after all the other init scripts.

You can put your own initialization stuff in here if you don’t

want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
[root@svr5 ~]# awk ‘{print $1,$2}’ /etc/rc.local //輸出文件的第1、2列
#!/bin/sh

This

You

want

touch /var/lock/subsys/local
結合管道過濾命令輸出:
[root@svr5 ~]# uname -a //正常的完整輸出
Linux svr5.tarena.com 2.6.18-348.el5 #1 SMP Wed Nov 28 21:22:00 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
[root@svr5 ~]# uname -a | awk ‘{print $1,$3,$12}’ //輸出第1、3、12字段
Linux 2.6.18-348.el5 x86_64
2)選項 -F 可指定分隔符
截取/etc/passwd文件的前7行,用來創建一個測試文件,操作如下:
[root@svr5 ~]# head -7 /etc/passwd > passwd.txt
[root@svr5 ~]# cat passwd.txt
root❌0:0:root:/root:/bin/bash
bin❌1:1:bin:/bin:/sbin/nologin
daemon❌2:2:daemon:/sbin:/sbin/nologin
adm❌3:4:adm:/var/adm:/sbin/nologin
lp❌4:7:lp:/var/spool/lpd:/sbin/nologin
sync❌5:0:sync:/sbin:/bin/sync
shutdown❌6:0:shutdown:/sbin:/sbin/shutdown
輸出passwd.txt文件中以分號分隔的第1、7個字段,顯示的不同字段之間以逗號隔開,操作如下:
[root@svr5 ~]# awk -F: ‘{print $1","$7}’ passwd.txt
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
或者:
[root@svr5 ~]# awk -F “:” ‘{print $1","$7}’ passwd.txt
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
awk過濾處理也支持以指定的字符串作爲分隔,比如以“in”分隔,輸出第1、3個字段的文本:
[root@svr5 ~]# awk -F “in” ‘{print $1,$3}’ passwd.txt
root❌0:0:root:/root:/b
b :/b
daemon❌2:2:daemon:/sb /nolog
adm❌3:4:adm:/var/adm:/sb
lp❌4:7:lp:/var/spool/lpd:/sb
sync❌5:0:sync:/sb /sync
shutdown❌6:0:shutdown:/sb /shutdown
awk還識別多種單個的字符,比如以“:”或“/”分隔,輸出第1、10個字段:
[root@svr5 ~]# awk -F [?] ‘{print $1,$10}’ passwd.txt
root bash
bin nologin
daemon nologin
adm sbin
lp
sync sync
shutdown shutdown
3)特殊的內置變量
注意:調用awk的內置變量時,不需要加前置 $ 符號。
比如,使用awk輸出當前操作的文件名、當前處理的行號:
[root@svr5 ~]# awk ‘{print FILENAME,NR}’ passwd.txt
passwd.txt 1
passwd.txt 2
passwd.txt 3
passwd.txt 4
passwd.txt 5
passwd.txt 6
passwd.txt 7
輸出每次處理的行號,以及當前行以“:”分隔的字段個數:
[root@svr5 ~]# awk -F: ‘{print NR,NF}’ passwd.txt
1 7
2 7
3 7
4 7
5 7
6 7
7 7
輸出當前用戶的passwd記錄(第1列的值與系統變量USER的值相同):
[root@svr5 ~]# echo $USER //確認當前用戶
root
[root@svr5 ~]# awk -F: ‘$1ENVIRON[“USER”]{print $0}’ passwd.txt
root❌0:0:root:/root:/bin/bash //輸出當前用戶的記錄
注意:$0表示正在處理的整行文本,可以省略(默認即輸出整行);當編輯指令是輸出匹配的整行文本時,整個{print $0}都可以不寫。
上述操作可簡寫爲:
[root@svr5 ~]# awk -F: '$1
ENVIRON[“USER”]{print}’ passwd.txt
root❌0:0:root:/root:/bin/bash
或者:
[root@svr5 ~]# awk -F: ‘KaTeX parse error: Expected 'EOF', got '#' at position 289: …: [root@svr5 ~]#̲ awk 'BEGIN{A=1…/{x++} END{print x}’ /etc/passwd
29
當然,這個例子比較簡單(效果與egrep -c ‘<bash$’ /etc/passwd 相同),此處僅僅是用來說明awk三種處理時機的用法。在實際工作中,利用awk的這種處理流程可以完成許多更復雜的任務。
步驟二:利用awk提取本機的IP地址、根分區使用率
1)提取IP地址
分步實現的思路及操作參考如下——
通過ifconfig eth0查看網卡信息,其中包括IP地址:
[root@svr5 ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:82:09:E9
inet addr:192.168.4.4 Bcast:192.168.4.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe82:9e9/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:358524 errors:0 dropped:0 overruns:0 frame:0
TX packets:230638 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:44470760 (42.4 MiB) TX bytes:64236279 (61.2 MiB)
結合grep獲得包含IP地址的那一行:
[root@svr5 ~]# ifconfig eth0 | grep “inet addr:”
inet addr:192.168.4.4 Bcast:192.168.4.255 Mask:255.255.255.0
再結合awk過濾出默認分隔的第2列:
[root@svr5 ~]# ifconfig eth0 | grep “inet addr:” | awk ‘{print $2}’
addr:192.168.4.4
進一步結合awk過濾出以“:”分隔的第2列:
[root@svr5 ~]# ifconfig eth0 | grep “inet addr:” | awk ‘{print $2}’ | awk -F: ‘{print $2}’
192.168.4.4
2)提取根分區使用率
分步實現的思路及操作參考如下——
通過df命令查看根分區的使用情況,其中包括使用率:
[root@svr5 ~]# df -hT /
文件系統 類型 容量 已用 可用 已用% 掛載點
/dev/sda2 ext3 19G 7.2G 11G 40% /
輸出上述結果中最後一行的第6列:
[root@svr5 ~]# df -hT / | tail -1 | awk ‘{print $6}’
40%
步驟三:格式化輸出/etc/passwd文件
1)任務需求及實現思路分析
根據任務要求的結果,輸出的內容包括三個部分:列表頭、用戶信息、列表尾。
由於/etc/passwd文件中的用戶記錄是單一的以“:”分隔,而且恰好awk本身就已經支持“前、中、後”三段式處理,所以用awk處理是再合適不過了。通過awk的內置變量NR即可獲得處理的記錄行數,因此只要設置正確的輸出即可。
2)根據實現思路編寫、驗證awk過濾語句
輸出信息時,可以使用“\t”顯示Tab製表位:
[root@svr5 ~]# awk -F: ‘BEGIN{print “User\tUID\tHome”}
{print $1"\t"$3"\t"$6} END{print “Total “NR” lines.”}’ /etc/passwd
User UID Home
root 0 /root
bin 1 /bin
daemon 2 /sbin
adm 3 /var/adm
lp 4 /var/spool/lpd
sync 5 /sbin
… …
iamkiller 1234 /opt/.private/iamkiller
nsd001 0 /home/nsd001
nsd002 1236 /home/nsd002
nsd003 1237 /home/nsd003
postfix 89 /var/spool/postfix
Total 67 lines.

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