1. 程式人生 > >文本三劍客之awk基礎操作

文本三劍客之awk基礎操作

line 範圍 item之間 $nf 可選 小數點 expr i++ 科學計數法

1. awk基本介紹

功能說明:gawk - pattern scanning and processing language
awk是GNU項目,所以其實際的命令為gawk,因awk命令的二進制文件鏈接到gawk,所以awk命令亦是gawk命令。

1.1 描述

Gawk is the GNU Project‘s implementation of the AWK programming language. It conforms to the definition of the language in the POSIX 1003.1 Standard. This version in turn is based on the description in The AWK Programming Language, by Aho, Kernighan, and Wein‐berger. Gawk provides the additional features found in the current version of UNIX awk and a number of GNU-specific extensions.

1.2 基本格式

awk [option]  ‘program’  FILE1 FILE2…

program:由PATTERN + { statements }組成,statements多語句之間用分號進行分隔;

命令選項:

-Ffs:fs為指定輸入時的字段分隔符,fs可以是字符串或正則表達式,如-F: 
-v var=value:自定義變量,使用時會將該變量傳遞給awk內部;
-f scripfile:從腳本文件中讀取awk命令;

PS:awk可以處理文件中的內容,也可以讀取來自stdin的輸入。

1.3 常用命令結構

awk  ‘BEGIN{ statements }{ statements }END{ statements }‘  FILE

PS:單引號中的三個組成部分都是可選的,且任一部分都可單獨出現。

工作原理:

Step1. 在開始處理FILE或stdin中的內容之前,先執行一次BEGIN{ statements }語句(其僅執行一次);
Step2. 從FILE中讀取一行,然後執行{ statements }語句塊,再讀取第二行,接著執行{ statements }。重復這個循環過程,直到FILE全部被讀取完畢;
Step3. FILE內容在被{ statements }處理完畢後,接著執行一次END{ statements }‘語句塊結束awk命令(其僅執行一次)。

2. 常用功能

2.1 變量

1)內建變量

FS:輸入字段分隔符(input filed seperator),默認為空白字符;
OFS:輸出字段分隔符(output field seperator),默認為一個空白字符;
RS:輸入記錄分隔符(input record seperator),默認為一個換行符;
ORS:輸出記錄分隔符(output record seperator),默認為一個換行符;
NF:字段數(number of field),NF表示每行的字段總數,$NF表示最後一個字段;
NR:記錄數或行數(number of record),awk後接單個file表示行號;
FNR:多文件行數(file number of record),awk後接多個文件時,分別顯示其行號;
ARGC:命令行參數個數;
ARGV:參數數組,元素包含命令行所給出的各參數;
$0:表示file中當前行的內容;
$n:表示file中記錄的第n個字段;

:awk在引用變量時,無需加$符號,$n、$0、$NF等特殊變量除外。
2)自定義變量
a. 使用選項-v 定義

awk –v var=value  #變量名區分字符大小寫

b. 在program中直接定義

awk ‘var=value’

2.2 運算操作符

1)算術運算符
加+、減-、乘、除/、冪^、取余%
2)賦值運算符
=、+=、-=、=、/=、^=、%=、++、--
如:a+=5等價於a=a+5,其它亦同。
:i++和++i雖都等於i=i+1,但區別如下:
  i++ :先引用後增加,先在i所在的表達式中使用i的當前值,後讓i加1;
  ++i :先增加後引用,讓i先加1,然後在i所在的表達式中使用i的新值;
  i+=a:相當於i=i+a。i=i+a 比 i+=a多了一次對變量 i 的運算,後者效率高;
3)比較運算符
\>、>=、<、<=、!=、==
4)邏輯運算符
|| :邏輯或
&&:邏輯與
! :邏輯非

2.3 其它操作符

1)正則模式匹配符
~:匹配正則
!~:不匹配正則
2)C條件表達式:(? 和 : 結合)

selector?if-true-expression:if-false-expression

2.4 運算符優先級

下表中級別越高,則優先級越高。
技術分享圖片

3. program部分

program組成部分:PATTERN + { statements }

3.1 PATTERN:模式

1)/正則表達式/:僅處理能被正則模式匹配到的行;
2)關系表達式(relational expression):使用運算符進行操作;
 運算結果有“真”有“假”,其僅處理為“真”的結果,“真”表示為非0值或非空字符串。
3)行範圍:搭配NR使用
4)空模式:awk默認模式,其匹配file的每一行
5)BEGIN/END模式

3.2 {statements}:多命令語句

以下為語句的組成部分:
1)一般表達式;
2)變量或數組賦值;
3)輸入輸出語句;
4)函數調用;
內置:
 int( x ):返回 x 的截斷至整數的值;
 rand( ):返回任意數字 n,其中 0 <= n < 1;
 sin( x ):返回 x 的正弦;x 是弧度;
自定義:function_name(argu1,argu2…)
5)控制流語句
if語句、while語句、do-while語句和for語句等

3.3 打印輸出

3.3.1 print普通輸出

PS:print為普通輸出,默認會自動換行。
格式:{print item1,item2…}
1) item之間用逗號隔開,輸出時則為一個空白字符(OFS);
2) item可以是字符串、數值、變量、當前記錄的字段($n)或awk的表達式;
3) 若省略item,即{print}相當於{print $0}。

3.3.2 printf格式輸出

PS:printf會進行格式化輸出,默認不自動換行,換行需加換行符。
格式:{printf FORMAT,item1,item2…}
1) FORMAT為格式符,其必須給出;
2) 若要換行,需在FORMAT加上換行符“\n”;
3) 若有多個item時,要在FORMAT中分別指定對應item的格式化符號。
格式符

 %c:顯示字符的ASCII碼
 %d和%i:顯示有符號的十進制整數
 %e和%E:科學計數法數值顯示
 %f:浮點數(包括float和doulbe)
 %g和%G:以科學計數法或浮點形式顯示數值
 %o:八進制整數
 %u:顯示無符號十進制整數
 %x和%X:十六進制整數
 %p:指針
 %s:字符串
 %%:顯示%自身

修飾符

-:左對齊,如%-s
+:顯示數值的符號
n[.n]:n表示數字,第一個n控制字符或數值位數,第二個n則為小數點後的精度,如:%3.2f

轉義字符

 \b:後退
 \n:換行
 \r:回車
 \t:水平制表符
 \v:垂直制表符

4. 練習操作

1)通過定義外部變量的方式指定輸入輸出分隔符

~]# awk -v FS=":" -v OFS="++" ‘{print $1,$3,$6}‘ /etc/passwd

~]# awk -F: -v OFS="++" ‘{print $1,$3,$6}‘ /etc/passwd
root++0++/root
bin++1++/bin
daemon++2++/sbin
…..

2)FNR和NR的區別:

[root@Study ~]# awk ‘{print NR,$0}‘ /etc/issue /etc/redhat-release
1 CentOS release 6.5 (Final)
2 Kernel \r on an \m
3 
4 CentOS release 6.5 (Final)
[root@Study ~]# awk ‘{print FNR,$0}‘ /etc/issue /etc/redhat-release
1 CentOS release 6.5 (Final)
2 Kernel \r on an \m
3 
1 CentOS release 6.5 (Final)

3)NF和$NF的區別:

[root@Study ~]# echo -e "line1 f1 f2\nline2 f3 f4\nline4 f5 f6" | awk ‘{print NF,$NF,$(NF-1)}‘
3 f2 f1
3 f4 f3
3 f6 f5

4)ARGC和ARGV操作

[root@Study ~]# awk ‘BEGIN{print ARGC}‘ /etc/issue /etc/passwd /etc/fstab 
4
[root@Study ~]# awk ‘BEGIN{print ARGV[2]}‘ /etc/issue /etc/passwd /etc/fstab 
/etc/passwd
[root@Study ~]# awk ‘BEGIN{print ARGV[0]}‘ /etc/issue /etc/passwd /etc/fstab 
awk

5)在program中進行變量賦值:

~]# awk ‘BEGIN{var="Hello World";print var}‘
Hello World

6)printf的用法

~]#  awk -F: ‘{printf "Username:%-10s, UID:%i\n",$1,$3}‘ /etc/passwd |tail -5
Username:nobody    , UID:99
Username:vcsa      , UID:69
Username:saslauth  , UID:499
Username:postfix   , UID:89
Username:sshd      , UID:74

7)模式匹配

~]#  awk -F: ‘/^root/,/^sync/{print $1}‘ /etc/passwd
root
bin
daemon
adm
lp
sync

8)行範圍匹配:

~]# awk ‘NR<=5‘ /etc/fstab
~]# awk -F: ‘(NR>=10&&NR<=20){print $1}‘ /etc/passwd
~]# awk ‘NR>=10&&NR<=20‘ /etc/passwd
~]# awk ‘NR==10,NR==20‘ /etc/passwd

9)關系表達式

~]# awk -F: ‘$3>=500{printf "%-15s %5i\n",$1,$3}‘ /etc/passwd
rick              500
superlong         501
boy               502
~]# awk ‘$3=="ext4"{print $1,$2,$3}‘ /etc/fstab

或以正則模式進行匹配:

~]# awk ‘$3~/\<ext4\>/{print $1,$2,$3}‘ /etc/fstab  
UUID=5c573541-a198-4ed1-9b9f-a5ee81147c30 / ext4
UUID=e0038068-bb37-4873-b657-4347a1ffc975 /boot ext4 

10)條件表達式

~]# awk -F: ‘{$3>=500?user="Common User":user="root or SysUser";printf "%-10s,%5i: %-15s\n",$1,$3,user}‘ /etc/passwd | tail -6
saslauth  ,  499: root or SysUser
postfix   ,   89: root or SysUser
sshd      ,   74: root or SysUser
rick      ,  500: Common User    
superlong ,  501: Common User    
boy       ,  502: Common User   

11)BEGIN和END模式

~]# seq 5 |awk ‘BEGIN{printf "Summation\n=========\n"}{print $0"+";sum+=$1}END{print "=========";print sum}‘
Summation
=========
1+
2+
3+
4+
5+
=========
15

文本三劍客之awk基礎操作