Linux awk使用方法~~整理


目錄


 

  1. awk行處理方式
  2. awk命令格式
    1. 命令行格式
    2. 腳本格式
  3. 命令行格式——基本格式
  4. awk內置變量
  5. awk內置函數
  6. 測試數據
  7. awk變量和函數使用實例
  8. 邏輯判斷式
  9. 擴展格式
  10. BEGIN 和 END

 

 


 

 

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
小紅
小花
小可
小冰

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM