標籤:
awk是Unix系統中文本處理工具,叫AWK是因為其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字元。
使用awk的方式有:
1.命令列方式
awk [-F field-separator] ‘commands‘ input-file(s)其中,commands 是真正awk命令,[-F 域分隔字元]是可選的。 input-file(s) 是待處理的檔案。
在awk中,檔案的每一行中,由域分隔字元分開的每一項稱為一個域。通常,在不指名-F域分隔字元的情況下,預設的域分隔字元是空格。
command 命令需要在花括弧中定義。
2.將所有的awk命令插入一個單獨檔案,然後調用:awk -f awk-script-file input-file(s)其中,-f選項載入awk-script-file中的awk指令碼,input-file(s)跟上面的是一樣的。
以etc/passwd為例,說明awk使用。
~$ cat passwd.log
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin
各個冒號分隔字元含義:
login_name:passwd:UID:GID:user_name:home_dir:shell_path
1. 列印
[email protected]:~# awk -F ‘:‘ ‘{print $1, $4}‘ passwd.logroot 0daemon 1bin 2man 12mail 8nobody 65534ym65536 1000sshd 65534
- 其中單引號中的被大括弧括著的就是awk的語句,注意,其只能被單引號包含。
- 其中的$1..$n表示第幾例。註:$0表示整個行。
格式化輸出和C類似
[email protected]:~# awk -F ‘:‘ ‘{printf "%-8s %-8s\n", $1, $4}‘ passwd.logroot 0 daemon 1 bin 2 man 12 mail 8 nobody 65534 ym65536 1000 sshd 65534 2、過濾
a) 過濾條件:GID=65534且shell path = /bin/sh
[email protected]:~# awk -F: ‘$4==65534 && $7=="/bin/sh"‘ passwd.lognobody:x:65534:65534:nobody:/nonexistent:/bin/sh
其中的“==”為比較子。其他比較子:!=, >, <, >=, <=
b) 顯示GID>10的行
[email protected]:~# awk -F: ‘$4>10 {print $0}‘ passwd.logman:x:6:12:man:/var/cache/man:/bin/shnobody:x:65534:65534:nobody:/nonexistent:/bin/shym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bashsshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin3、內建變數
awk的一些內建變數:
| $0 |
目前記錄(這個變數中存放著整個行的內容) |
| $1~$n |
目前記錄的第n個欄位,欄位間由FS分隔 |
| FS |
輸入欄位分隔符號 預設是空格或Tab |
| NF |
目前記錄中的欄位個數,就是有多少列 |
| NR |
已經讀出的記錄數,就是行號,從1開始,如果有多個檔案話,這個值也是不斷累加中。 |
| FNR |
目前記錄數,與NR不同的是,這個值會是各個檔案自己的行號 |
| RS |
輸入的記錄分隔字元, 預設為分行符號 |
| OFS |
輸出欄位分隔符號, 預設也是空格 |
| ORS |
輸出的記錄分隔字元,預設為分行符號 |
| FILENAME |
當前輸入檔案的名字 |
列印行號大於6的行的資訊:
[email protected]:~# awk -F ‘:‘ ‘NR > 6 {print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}‘ passwd.log filename:passwd.log,linenumber:7,columns:7,linecontent:ym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bashfilename:passwd.log,linenumber:8,columns:7,linecontent:sshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin4、BEGIN/END
[email protected]:~# awk -F: ‘BEGIN {print "longin UID"} {print $1,$3} END {print "END"}‘ passwd.loglongin UIDroot 0daemon 1bin 2man 6mail 8nobody 65534ym65536 1000sshd 114END
awk工作流程是這樣的:先執行BEGING,然後讀取檔案,讀入有/n分行符號分割的一條記錄,然後將記錄按指定的域分隔字元劃分域,填充域,$0則表示所有域,$1表示第一個域,$n表示第n個域,隨後開始執行模式所對應的動作action。接著開始讀入第二條記錄······直到所有的記錄都讀完,最後執行END操作。
5、字串匹配
awk使用Regex進行匹配
a) 匹配第四列(GID)為65534的行,然後列印1,3列。
[email protected]:~# awk -F: ‘$4 ~ /65534/ {print $1,$3}‘ OFS=‘\t‘ passwd.log nobody 65534sshd 114
//中的內容即為要匹配的內容。
b) 向grep一樣匹配root字串
[email protected]:~# awk -F: ‘/root/‘ passwd.log root:x:0:0:root:/root:/bin/bash
c) 匹配root或者ym
[email protected]:~# awk -F: ‘/root|ym/‘ passwd.log root:x:0:0:root:/root:/bin/bashym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash
6、if語句
awk中的if語句和C語言類似,使用如下:
if (expression){ statement1;} else if (expression1) { statement2;} else { statement3;}
#注意每條語句以分號;結尾
把第一列匹配root或ym的行放入檔案1.txt,其餘的放入檔案2.txt
awk -F: ‘{if($1 ~ /root|ym/) print > "1.txt"; else print > "2.txt"}‘ passwd.log [email protected]:~# ls1.txt 2.txt passwd.logroot:x:0:0:root:/root:/bin/bashym65536:x:1000:1000:ubuntu-10-10,,,:/home/ym65536:/bin/bash[email protected]:~# cat 2.txt daemon:x:1:1:daemon:/usr/sbin:/bin/shbin:x:2:2:bin:/bin:/bin/shman:x:6:12:man:/var/cache/man:/bin/shmail:x:8:8:mail:/var/mail:/bin/shnobody:x:65534:65534:nobody:/nonexistent:/bin/shsshd:x:114:65534::/var/run/sshd:/usr/sbin/nologin7、統計
統計當前路徑下txt檔案大小的和:
[email protected]:~# ls -l *.txt-rw-r--r-- 1 root root 92 2015-02-23 23:11 1.txt-rw-r--r-- 1 root root 236 2015-02-23 23:11 2.txt[email protected]:~# ls -l *.txt |awk ‘BEGIN{sum=0} {sum += $5} END{print "txt file size is", sum}‘txt file size is 328
統計GID=65534的行的個數:
[email protected]:~# awk -F: ‘BEGIN{count=0} {if($4==65534) count++} END{print count}‘ passwd.log 2
Linux awk 命令