Linux 文本處理工具awk
阿新 • • 發佈:2018-05-08
linux awk很好用的文本處理工具,尤其是變量跟控制語句,使用超贊。
個人理解大致流程如下
個人理解大致流程如下
1、正常輸出
# $0表示正行 默認是按照行分割 $1 $2
#-----------------------------------------------------------------
[root@node1 test]# awk ‘{print "hello ",$2}‘ fstab
hello
hello
hello /etc/fstab
hello Created
2、變量
#FS:input field seperator, 輸入 在行裏面裏面的分割符,默認為空白字符; #OFS:output field seperator,輸出 在行裏面裏面的分割符,默認為空白字符; #----------------------------------------------------------------- [root@node1 test]# awk -F‘ ‘ ‘{print $4}‘ fstab [root@node1 test]# awk -v FS=‘ ‘ ‘{print $4}‘ fstab [root@node1 test]# awk -v FS=‘ ‘ -v OFS=‘:‘ ‘{print $3,$4}‘ fstab #OFS 相當於把$3,$4 替換成$3 【OFS】$4 by:anaconda
#RS:input record seperator, 輸入 默認為行分割符; #ORS:output record seperator, 輸出 默認為行分割符; (這兩個一般很少用,文本從本來一行一行,換成其他格式) #----------------------------------------------------------------- [root@node1 test]# awk -v RS=‘\n‘ -v ORS=‘\n‘ ‘{print $1}‘ fstab #默認 [root@node1 test]# awk -v RS=‘ ‘ -v ORS=‘:‘ ‘{print "hello ",$2}‘ fstab # hello #:hello #:hello ......
#NF number of field 每行字段數目 $#
#-----------------------------------------------------------------
[root@node1 test]# awk ‘{print NF}‘ fstab
#最後一個字段值
#-----------------------------------------------------------------
[root@node1 test]# awk ‘{print $NF}‘ fstab
#NR:number of record, 行號; #----------------------------------------------------------------- [root@node1 test]# awk ‘{print NR}‘ fstab #FNR:各文件分別計數;行數; #----------------------------------------------------------------- [root@node1 test]# awk ‘{print FNR}‘ fstab fstab
#自定義變量 -v var=value 變量名區分字符大小寫;
#-----------------------------------------------------------------
[root@node1 test]# awk -v test=‘hello world‘ ‘{print test}‘ fstab
hello world
[root@node1 test]# awk ‘{test="hello world"; print test}‘ fstab
hello world
3、printf命令 用來顯示樣式
(1) FORMAT必須給出;
(2) 不會自動換行,需要顯式給出換行控制符,\n
(3) FORMAT中需要分別為後面的每個item指定一個格式化符號;
格式符:
%c: 顯示字符的ASCII碼;
%d, %i: 顯示十進制整數;
%e, %E: 科學計數法數值顯示;
%f:顯示為浮點數;
%g, %G:以科學計數法或浮點形式顯示數值;
%s:顯示字符串;
%u:無符號整數;
%%: 顯示%自身;
修飾符:
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點後的精度;
-: 左對齊
+:顯示數值的符號
[root@node1 test]# awk ‘{printf "%50s\n",$1}‘ fstab
#
UUID=7ceb028a-a8b8-467c-b6d4-36910c06c5ac
UUID=3d81b92c-abeb-41f5-8de0-b46d3ffbcf4c
UUID=943c7e04-b733-42fe-a1e2-eabf93693f6b
4、操作符
算術操作符:x+y, x-y, x*y, x/y, x^y, x%y -x +x: 轉換為數值;字符串操作符:沒有符號的操作符,字符串連接
賦值操作符:=, +=, -=, *=, /=, %=, ^= ++, --
比較操作符:>, >=, <, <=, !=, ==
模式匹配符: ~:是否匹配 !~:是否不匹配
邏輯操作符:&& || !
函數調用:function_name(argu1, argu2, ...)
條件表達式:selector?if-true-expression:if-false-expression
#-----------------------------------------------------------------
[root@node1 test]# awk -F: ‘{ $7~"/bash" ? is_bash="yes":is_bash="no";age=8+10;print $1,age,$7,is_bash}‘ passwd
root 18 /bin/bash yes
bin 18 /sbin/nologin no
5、定界
[root@node1 test]# awk ‘!/^UUID/{printf "%-50s\n",$1}‘ fstab #正則
[root@node1 test]# awk ‘/^UUID/{printf "%-50s\n",$1}‘ fstab
[root@node1 test]# awk ‘$3>1000{print $1,$3}‘ /etc/passwd #表達式
[root@node1 test]# awk -F: ‘$NF~"/bash"{print $1,$3}‘ /etc/passwd
[root@node1 test]# awk -F: ‘/^sync/,/^halt/{print $1,$3}‘ /etc/passwd
sync 5
shutdown 6
halt 7
[root@node1 test]# awk -F: ‘(NR>=6&&NR<=8){print NR,$1,$3}‘ /etc/passwd
[root@node1 test]# awk -F: ‘BEGIN{print "username uid \n---------"}{print $1,$3}‘ /etc/passwd
username uid
---------
root 0
bin 1
daemon 2
[root@node1 test]# awk -F: ‘{print "username uid \n---------";print $1,$3}‘ /etc/passwd
username uid
---------
root 0
username uid
---------
bin 1
username uid
6、控制語句
#if(condition) {statments}
[root@node1 test]# awk ‘{if(NF>5) print $0}‘ /etc/fstab
#if(condition) {statments} else {statements}
[root@node1 test]# awk -F: ‘{if($3>=1000) printf "Common user: %s\n",$1 ;else printf "root or Sysuser: %s\n",$1}‘ /etc/passwd
#-----------------------------------------------------------------
#while(conditon) {statments}
[root@node1 test]# awk ‘/^UUID/{i=1;while(i<=NF) {print $i;i++}}‘ fstab
#do statement while(condition) 先執行在判斷
[root@node1 test]# awk ‘/^UUID/{i=1;do {print $i;i++;} while(i<=NF)}‘ fstab
#-----------------------------------------------------------------
#for(expr1;expr2;expr3) statement
[root@node1 test]# awk ‘{for(i=0;i<NF;i++){print $i}}‘ fstab
[root@node1 test]# awk ‘BEGIN{names["a"]="zander"; names["b"]="marvin";for(i in names){print i,names[i] }}‘ fstab #只能是關聯數組 names[0]="zander"; 這個也是關聯數組
a zander
b marvin
#-----------------------------------------------------------------
#switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}
#next 提前結束對本行的處理而直接進入下一行;
#-----------------------------------------------------------------
[root@node1 test]# awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
7、數組操作
關聯數組:array[index-expression]
#index in array
[root@node1 test]# awk ‘BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday"; if("mon" in weekdays){print weekdays["mon"]}else{print "not exist"}}‘
Monday
#for(var in array) {for-body}
[root@node1 test]# awk ‘BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}‘
統計 去重復
[root@node1 test]# netstat -tan | awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}‘
LISTEN 2
ESTABLISHED 3
8、函數
#rand():返回0和1之間一個隨機數;
#-----------------------------------------------------------------
[root@node1 test]# awk ‘BEGIN{print rand()}‘
0.237788
#length([s]):返回指定字符串的長度;
#-----------------------------------------------------------------
[root@node1 test]# awk ‘BEGIN{name="zander"; print length(name)}‘
6
#sub 替換 -----> 一次
#-----------------------------------------------------------------
[root@node1 test]# awk ‘BEGIN{name="zander"; print sub("a","A",name),name}‘
1 zAnder
#sub 替換 -----> 全部
#-----------------------------------------------------------------
[root@node1 test]# awk ‘BEGIN{name="zandera"; print gsub("a","A",name),name}‘
2 zAnderA
#split(s,a[,r]):以r為分隔符切割字符s,並將切割後的結果保存至a所表示的數組中;
#------------------------------------------------------------------
[root@node1 test]# netstat -tan|awk ‘/^tcp\>/{split($5,ip,":"); count[ip[1]]+=1;}END{for(i in count){print i,count[i]}}‘
Linux 文本處理工具awk