目錄
awk行處理方式
awk和sed一樣,一次處理一行內容;也可以對每行進行切片處理
awk命令格式
命令行格式
$ awk [options] 'command' files
腳本格式
$ awk -f scirpt_file files
基本格式
$ awk [options] 'command' files
command 由兩部分組成,分別是
1、pattern,可以是正則表達式或者邏輯判斷式
2、{ awk 命令 } 花括號括起來的是代碼段
awk內置變量
變量 | 含義 |
$0 | 當前記錄(整行的記錄) |
$1~$n | 當前記錄的第幾列 |
FILENAME | 輸入的文件名稱 |
FS | 輸入文件的字段分隔符(Fields Separator) |
RS | 輸入文件的記錄(每一行之間)的分隔符(Record Separator) |
NF | 當前行的字段數目(Number of Fields) |
NR | 當前記錄所在的行號 |
OFS | 輸出字段的分隔符 |
ORS | 輸出記錄的分隔符 |
awk函數
函數聲明 | 含義 |
length(str) | 返回str中字符的個數 |
int(num) | 返回num的整數部分 |
index(str1, str2) | 返回str2在str1中的索引,如果不存在就返回0 |
split(str, arr, separator) | 使用separator作為分隔符,將str切分為數組保存到arr中,返回數組的元素個數 |
printf(fmt, args) | 根據fmt格式化args,並輸出結果 |
sprintf(fmt, args) | 根據fmp格式化args,並返回格式化后的字符串 |
substr(str, pos, len) | 返回str中從pos開始,長度為len個字符的子字符串 |
tolower(str) | 返回str轉換為小寫字母后的副本 |
toupper(str) | 返回str轉換為大寫字母后的副本 |
測試數據
-> # cat data.txt 小紅 female 一年級 BeiJing 90 Yes 小花 female 一年級 ShangHai 55 小明 male 三年級 BeiJing 90 小可 female 一年級 ChongQing 70 小林 male 一年級 ChongQing 90 Yes 小飛 male 二年級 GuangDong 65 小波 male 一年級 HangZhou 90 No 小康 male 四年級 ShenZhen 65 No 小雷 male 一年級 FuJian 70 小冰 female 五年級 BeiJing 90
測試awk變量和函數
打印每一行的行號、字段數、以及每一行的內容
-> # awk '{print "row:" NR "\t" "fields:" NF "\t" $0}' data.txt row:1 fields:6 小紅 female 一年級 BeiJing 90 Yes row:2 fields:5 小花 female 一年級 ShangHai 55 row:3 fields:5 小明 male 三年級 BeiJing 90 row:4 fields:5 小可 female 一年級 ChongQing 70 row:5 fields:6 小林 male 一年級 ChongQing 90 Yes row:6 fields:5 小飛 male 二年級 GuangDong 65 row:7 fields:6 小波 male 一年級 HangZhou 90 No row:8 fields:6 小康 male 四年級 ShenZhen 65 No row:9 fields:5 小雷 male 一年級 FuJian 70 row:10 fields:5 小冰 female 五年級 BeiJing 90
打印所有的人名、城市
-> # awk '{print $1 "\t" $4}' data.txt 小紅 BeiJing 小花 ShangHai 小明 BeiJing 小可 ChongQing 小林 ChongQing 小飛 GuangDong 小波 HangZhou 小康 ShenZhen 小雷 FuJian 小冰 BeiJing
使用printf來格式化打印用戶信息
-> # awk -F ':' '{printf("Line:%s Fields:%s User:%s\n", NR, NF, $1)}' /etc/passwd Line:1 Fields:7 User:root Line:2 Fields:7 User:bin Line:3 Fields:7 User:daemon Line:4 Fields:7 User:adm Line:5 Fields:7 User:lp Line:6 Fields:7 User:sync Line:7 Fields:7 User:shutdown
打印用戶id大於100的行號和用戶名,其他用戶不打印,輸出hello
-> # awk -F ':' '{ > if ($3 > 100) { > printf("Line:%s Fields:%s User:%s UID:%s\n", NR, NF, $1, $3) > } else { > print "hello" > } > }' /etc/passwd
找出服務器訪問日志中,出現Error的時間
-> # sed -n '/Error/ p' access_log | awk '{print $1}' -> # awk '/Error/ {print $1}' access_log
邏輯判斷式
注意,邏輯判斷式是在{ awk命令 }前面的
~,!~ 是否匹配正則表達式,后面跟一個正則表達式
-> # #查詢主機中,用戶名包含'g'的用戶,打印出用戶名和UID -> # awk -F ':' '$1 ~ /g/ {print "User:"$1 "\t" "UID:"$3}' /etc/passwd User:games UID:12 User:libstoragemgmt UID:998 User:syslog UID:996 User:yingjie UID:1005 -> # #查詢主機中,用戶名不包含'g'的用戶,打印出用戶名和UID -> # awk -F ':' '$1 !~ /g/ {print "User:"$1 "\t" "UID:"$3}' /etc/passwd
==,!= , >=,<=,<,> ,||,&& 用於判斷大小、是否相等、邏輯關系
-> # #打印分數高於70,或者低於或者等於60的記錄 -> # awk '$5 > 70 || $5 < 60 {print $0}' data.txt 小紅 female 一年級 BeiJing 90 Yes 小花 female 一年級 ShangHai 55 小明 male 三年級 BeiJing 90 小林 male 一年級 ChongQing 90 Yes 小波 male 一年級 HangZhou 90 No 小冰 female 五年級 BeiJing 90
擴展格式
$ awk [options] 'command' file
擴展格式是指,command擴展,格式如下:
BEGIN { command1 } pattern { awk命令 } END { command2 }
其中 BEGIN中的command1,會在讀入第一行之前執行,並且只執行一次。接着循環執行中間的awk命令、
然后END后面的command2,會在文件所有行都讀完之后,並執行一次command2。
-> # awk 'BEGIN {print "start"} /female/ {print $0} END {print "end"}' data.txt start 小紅 female 一年級 BeiJing 90 Yes 小花 female 一年級 ShangHai 55 小可 female 一年級 ChongQing 70 小冰 female 五年級 BeiJing 90 end
BEGIN和END
一般在BEGIN中可以做一下事情:
1、定義分隔符
2、定義表頭
自定義分割符、輸出時使用的分隔符
FS (fields separator)
OFS( output fields separator)
-> # awk 'BEGIN{FS=" ";OFS="-"}{print $2,$1}' data.txt female-小紅 female-小花 male-小明 female-小可 male-小林 male-小飛 male-小波 male-小康 male-小雷 female-小冰
定義表頭
-> # awk ' > BEGIN {print "Name" "\t" "Gender" "\t" "Grade" "\t" "Addr" "\t" "Score" "\t" "VIP"} > NF == 6 {print $0} > END {print "----------end-----------"}' data.txt Name Gender Grade Addr Score VIP 小紅 female 一年級 BeiJing 90 Yes 小林 male 一年級 ChongQing 90 Yes 小波 male 一年級 HangZhou 90 No 小康 male 四年級 ShenZhen 65 No ----------end-----------
統計當前文件夾下,文件總大小
[root@VM_0_8_centos test]# ls -l total 8 -rw-r--r-- 1 root root 367 Sep 16 11:51 data.txt -rw-r--r-- 1 root root 1803 Aug 17 00:14 test.cpp [root@VM_0_8_centos test]# ls -l | awk 'BEGIN {size=0} {size+=$5} END {print "Size is " size}' Size is 2170
統計文件中非空行的行數
[root@VM_0_8_centos test]# cat demo.txt 11111 22222 33333 44444 [root@VM_0_8_centos test]# awk 'BEGIN {count=0} $0 !~ /^$/ {count += 1} END {print "Not empty line count " count}' demo.txt Not empty line count 4
統計女生的數量
-> # awk ' > BEGIN {count = 0} > { > if ($2 == "female") { > name[count++] = $1 > } > } > END { > print "tot " count > for (i = 0; i < count; i++) { > print name[i] > } > }' data.txt tot 4 小紅 小花 小可 小冰