最近基本把shell 指令碼編寫的內容學習了一遍,看指令碼輕鬆了,但是實際上手還有一定的困難,所以決定找點例子來實練,畢竟有句話說的很好,“紙上得來終覺淺,絕知此事要躬行”;很有道理,最近深刻體會到了!通過實練也算是《shell知識點補充》板塊的進階吧!攻克shell,再說python!!
1、awk
awk 用法:awk ' pattern {action} '
awk “/關鍵字/” 檔案名稱
Loong:/home/yee/shell# awk '/root/' xaa
顯示xaa檔案中帶root的行
root:x:0:0:root:/root:/bin/bash
Loong:/home/yee/shell# awk '/3/' xaa 顯示xaa檔案中帶3的行
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Loong:/home/yee/shell# cat last.txt 用例檔案內容
root pts/6 172.16.7.94 Wed Oct 31 10:09 still logged in
yee pts/5 172.16.7.97 Wed Oct 31 10:09 still logged in
yee pts/1 172.16.7.95 Wed Oct 31 10:06 still logged in
root pts/6 172.16.7.94 Tue Oct 30 14:52 - 19:38 (04:45)
yee pts/5 172.16.3.89 Tue Oct 30 08:36 - 19:43 (11:06)
yee pts/1 172.16.7.94 Tue Oct 30 08:34 - 19:38 (11:04)
loongson pts/6 172.16.7.94 Mon Oct 29 15:12 - 19:23 (04:11)
yee pts/5 172.16.3.89 Mon Oct 29 08:59 - 19:08 (10:08)
loongson pts/1 172.16.7.94 Mon Oct 29 08:53 - 19:24 (10:31)
yee pts/5 172.16.7.94 Fri Oct 26 10:53 - 17:27 (06:33)
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell# awk '$1 == "yee"' last.txt 顯示第一個變數為yee的行,注意必須帶雙引號
yee pts/5 172.16.7.97 Wed Oct 31 10:09 still logged in
yee pts/1 172.16.7.95 Wed Oct 31 10:06 still logged in
yee pts/5 172.16.3.89 Tue Oct 30 08:36 - 19:43 (11:06)
yee pts/1 172.16.7.94 Tue Oct 30 08:34 - 19:38 (11:04)
yee pts/5 172.16.3.89 Mon Oct 29 08:59 - 19:08 (10:08)
yee pts/5 172.16.7.94 Fri Oct 26 10:53 - 17:27 (06:33)
Loong:/home/yee/shell# awk '$1 > $2' last.txt 顯示出字串第一個大於第二個的行;
root pts/6 172.16.7.94 Wed Oct 31 10:09 still logged in
yee pts/5 172.16.7.97 Wed Oct 31 10:09 still logged in
yee pts/1 172.16.7.95 Wed Oct 31 10:06 still logged in
root pts/6 172.16.7.94 Tue Oct 30 14:52 - 19:38 (04:45)
yee pts/5 172.16.3.89 Tue Oct 30 08:36 - 19:43 (11:06)
yee pts/1 172.16.7.94 Tue Oct 30 08:34 - 19:38 (11:04)
yee pts/5 172.16.3.89 Mon Oct 29 08:59 - 19:08 (10:08)
yee pts/5 172.16.7.94 Fri Oct 26 10:53 - 17:27 (06:33)
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell# awk '{print NR,NF,$1,$NF}' last.txt 顯示檔案的目前記錄行號、域數(空格隔開也是一個)和每一行的第一個和最後一個域(字串)
1 10 root in
2 10 yee in
3 10 yee in
4 10 root (04:45)
5 10 yee (11:06)
6 10 yee (11:04)
7 10 loongson (04:11)
8 10 yee (10:08)
9 10 loongson (10:31)
10 10 yee (06:33)
11 0
12 7 wtmp 2012
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk '/loongson/ {print $1,$2+23}' last.txt 顯示檔案f匹配行的第一域、第二個域加23,不清楚為什麼被覆蓋了?
loongson 23
loongson 23
Loong:/home/yee/shell# awk '/loongson/ {print $1,$2}' last.txt
loongson pts/6
loongson pts/1
Loong:/home/yee/shell# awk '/loongson/ {print $1 $2}' last.txt
loongsonpts/6
loongsonpts/1
Loong:/home/yee/shell# awk '/loongson/ {print $1$2}' last.txt 逗號,表示顯示的兩個域有空格隔開
loongsonpts/6
loongsonpts/1
Loong:/home/yee/shell#
Loong:/home/yee/shell# df
檔案系統 1K-塊 已用 可用 已用% 掛載點
/dev/sda5 20641788 7509808 12083340 39% /
tmpfs 253472 16 253456 1% /lib/init/rw
udev 253472 656 252816 1% /dev
tmpfs 253472 16 253456 1% /dev/shm
/dev/sda6 126849780 2437976 117968136 3% /home
shm 253472 253472 0 100% /tmp
Loong:/home/yee/shell# df | awk '$4>10000000' 通過管道符獲得輸入,如:顯示第4個域滿足條件的行
檔案系統 1K-塊 已用 可用 已用% 掛載點
/dev/sda5 20641788 7509808 12083340 39% /
/dev/sda6 126849780 2437976 117968136 3% /home
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk -F "/" '{print $1}' last.txt 按照新的分隔字元“/”進行輸出第一個自訂的域
root pts
yee pts
yee pts
root pts
yee pts
yee pts
loongson pts
yee pts
loongson pts
yee pts
wtmp begins Wed Oct 10 09:34:03 2012 沒有找到 / ,全部當做第一個域輸出
Loong:/home/yee/shell# awk 'BEGIN {FS="/"}{print $1}' last.txt 按照新的分隔字元“/”進行輸出第一個自訂的域,方法二通過設定輸入分隔字元
root pts
yee pts
yee pts
root pts
yee pts
yee pts
loongson pts
yee pts
loongson pts
yee pts
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell# awk 'BEGIN {FS="."}{print $1}' last.txt
按照新的分隔字元“/”進行輸出第一個自訂的域,方法二通過設定輸入分隔字元
root pts/6 172
yee pts/5 172
yee pts/1 172
root pts/6 172
yee pts/5 172
yee pts/1 172
loongson pts/6 172
yee pts/5 172
loongson pts/1 172
yee pts/5 172
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell#
Loong:/home/yee/shell# Es="/"
Loong:/home/yee/shell# awk -F $Es '{print $1}' last.txt 按照環境變數Es的值做為分隔字元
root pts
yee pts
yee pts
root pts
yee pts
yee pts
loongson pts
yee pts
loongson pts
yee pts
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk -F '[/]''{print $1}' last.txt
root pts
yee pts
yee pts
root pts
yee pts
yee pts
loongson pts
yee pts
loongson pts
yee pts
wtmp begins Wed Oct 10 09:34:03 2012
Loong:/home/yee/shell# awk -F '[ :\t]''{print $1}' last.txt
按照Regex的值做為分隔字元來顯示指定輸出
root
yee
yee
root
yee
yee
loongson
yee
loongson
yee
wtmp
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk '$1 ~/root/
{print $1}' last.txt
root
root
Loong:/home/yee/shell# awk '$1 ~/root/ {print $3}' last.txt 顯示檔案中第一個域匹配root的行並輸出第三個域
172.16.7.94
172.16.7.94
Loong:/home/yee/shell# awk '{print
($1>$2 ? "high "$1: "low " $1)}' last.txt (運算式1?運算式2:運算式3) 相當於:
if (運算式1)
運算式2
else
運算式3
high root 如果條件成立,則執行運算式2,否則執行運算式3
high yee
high yee
high root
high yee
high yee
low loongson
high yee
low loongson
high yee
low
high wtmp
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk '/172.16.7.94/{$3=1000;print}' last.txt 找到匹配行後為變數$3賦值並列印該行,也可print $3指定列印變數
root pts/6 1000 Wed Oct 31 10:09 still logged in
root pts/6 1000 Tue Oct 30 14:52 - 19:38 (04:45)
yee pts/1 1000 Tue Oct 30 08:34 - 19:38 (11:04)
loongson pts/6 1000 Mon Oct 29 15:12 - 19:23 (04:11)
loongson pts/1 1000 Mon Oct 29 08:53 - 19:24 (10:31)
yee pts/5 1000 Fri Oct 26 10:53 - 17:27 (06:33)
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk '/yee/ {count++;} END {print "yee was found "count" times"}' last.txt END表示在所有輸入行處理完後進行處理
yee was found 6 times
Loong:/home/yee/shell#
Loong:/home/yee/shell# awk
'gsub(/\./,"dot");END {print $3}' last.txt gsub函數用字串替換. 再將結果輸出
root pts/6 172dot16dot7dot94 Wed Oct 31 10:09 still logged in
yee pts/5 172dot16dot7dot97 Wed Oct 31 10:09 still logged in
yee pts/1 172dot16dot7dot95 Wed Oct 31 10:06 still logged in
root pts/6 172dot16dot7dot94 Tue Oct 30 14:52 - 19:38 (04:45)
yee pts/5 172dot16dot3dot89 Tue Oct 30 08:36 - 19:43 (11:06)
yee pts/1 172dot16dot7dot94 Tue Oct 30 08:34 - 19:38 (11:04)
loongson pts/6 172dot16dot7dot94 Mon Oct 29 15:12 - 19:23 (04:11)
yee pts/5 172dot16dot3dot89 Mon Oct 29 08:59 - 19:08 (10:08)
loongson pts/1 172dot16dot7dot94 Mon Oct 29 08:53 - 19:24 (10:31)
yee pts/5 172dot16dot7dot94 Fri Oct 26 10:53 - 17:27 (06:33)
Wed
Loong:/home/yee/shell#
在awk中如需調用環境變數一定不能出現在單引號內:
Flag=abcd
awk '{print '$Flag'}' 用法不對,引號不配對,結果依賴環境
awk '{print "$Flag"}' 結果為$Flag
awk "{print '$Flag'}" 結果為$Flag
awk "{print \"$Flag\"}" 結果為abcd
單雙引號的差別是:shell對單引號中的內容不解釋,直接傳給awk,而對雙引號中的內容解釋後再傳給awk.
從以上例子可以看出awk主要的用法就是對行、字串的某些內容根據特定的判斷字元或定義來進行修改,主要方法有
(1)利用內建的參數NF,FS等設條件;
(2)利用/字元/,設條件;
(3)利用Regex[字元]設條件
(4)使用==,if,else;while,自加;大於,小於;for迴圈等
最後進行指定輸出。
更多用法參考:http://www.chinaunix.net/old_jh/24/691456.html