awk命令的使用
awk 是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據可以來自標準輸入(stdin)、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是linux/unix下的一個強大編程工具。它在命令行中使用,但更多是作爲腳本來使用。awk有很多內建的功能,比如數組、函數等,這是它和C語言的相同之處,靈活性是awk最大的優勢。
awk命令格式和選項
語法形式
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
常用命令選項
-
-F fs fs指定輸入分隔符,fs可以是字符串或正則表達式,如-F:,默認的分隔符是連續的空格或製表符
--v var=value 賦值一個用戶定義變量,將外部變量傳遞給awk
awk模式和操作
awk腳本是由模式和操作組成的。
模式
模式可以是以下任意一個:
- /正則表達式/:使用通配符的擴展集。
- 關係表達式:使用運算符進行操作,可以是字符串或數字的比較測試。
- 模式匹配表達式:用運算符
~
(匹配)和!~
(不匹配)。 - BEGIN語句塊、pattern語句塊、END語句塊:參見awk的工作原理
操作
操作由一個或多個命令、函數、表達式組成,之間由換行符或分號隔開,並位於大括號內,主要部分是:
- 變量或數組賦值
- 輸出命令
- 內置函數
- 控制流語句
awk腳本基本結構
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
一個awk腳本通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊3部分組成,這三個部分是可選的。任意一個部分都可以不出現在腳本中,腳本通常是被 單引號 或 雙引號 中,例如:
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename
awk的工作原理
awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
第一步:執行
BEGIN{ commands }
語句塊中的語句;第二步:從文件或標準輸入(stdin)讀取一行,然後執行
pattern{ commands }
語句塊,它逐行掃描文件,從第一行到最後一行重複這個過程,直到文件全部被讀取完畢。第三步:當讀至輸入流末尾時,執行
END{ commands }
語句塊。BEGIN語句塊* 在awk開始從輸入流中讀取行 之前 被執行,這是一個可選的語句塊,比如變量初始化、打印輸出表格的表頭等語句通常可以寫在BEGIN語句塊中。
END語句塊* 在awk從輸入流中讀取完所有的行 之後 即被執行,比如打印所有行的分析結果這類信息彙總都是在END語句塊中完成,它也是一個可選語句塊。
pattern語句塊* 中的通用命令是最重要的部分,它也是可選的。如果沒有提供pattern語句塊,則默認執行
{ print }
,即打印每一個讀取到的行,awk讀取的每一行都會執行該語句塊。示例*
echo -e "A line 1\nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }'
Start
A line 1
A line 2
End
當使用不帶參數的print
時,它就打印當前行,當print
的參數是以逗號進行分隔時,打印時則以空格作爲定界符。在awk的print語句塊中雙引號是被當作拼接符使用,例如:
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }'
v1 v2 v3
雙引號拼接使用:
echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3
{ }類似一個循環體,會對文件中的每一行進行迭代,通常變量初始化語句(如:i=0)以及打印文件頭部的語句放入BEGIN語句塊中,將打印的結果等語句放在END語句塊中。
awk內置變量(預定義變量)
說明:[A][N][P][G]表示第一個支持變量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
**$n** 當前記錄的第n個字段,比如n爲1表示第一個字段,n爲2表示第二個字段。
**$0** 這個變量包含執行過程中當前行的文本內容。
[N] **ARGC** 命令行參數的數目。
[G] **ARGIND** 命令行中當前文件的位置(從0開始算)。
[N] **ARGV** 包含命令行參數的數組。
[G] **CONVFMT** 數字轉換格式(默認值爲%.6g)。
[P] **ENVIRON** 環境變量關聯數組。
[N] **ERRNO** 最後一個系統錯誤的描述。
[G] **FIELDWIDTHS** 字段寬度列表(用空格鍵分隔)。
[A] **FILENAME** 當前輸入文件的名。
[P] **FNR** 同NR,但相對於當前文件。
[A] **FS** 字段分隔符(默認是任何空格)。
[G] **IGNORECASE** 如果爲真,則進行忽略大小寫的匹配。
[A] **NF** 表示字段數,在執行過程中對應於當前的字段數。
[A] **NR** 表示記錄數,在執行過程中對應於當前的行號。
[A] **OFMT** 數字的輸出格式(默認值是%.6g)。
[A] **OFS** 輸出字段分隔符(默認值是一個空格)。
[A] **ORS** 輸出記錄分隔符(默認值是一個換行符)。
[A] **RS** 記錄分隔符(默認是一個換行符)。
[N] **RSTART** 由match函數所匹配的字符串的第一個位置。
[N] **RLENGTH** 由match函數所匹配的字符串的長度。
[N] **SUBSEP** 數組下標分隔符(默認值是34)。
轉義序列
\\ \自身
\$ 轉義$
\t 製表符
\b 退格符
\r 回車符
\n 換行符
\c 取消換行
示例
echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print "Line No:"NR", No of fields:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}'
Line No:1, No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
Line No:2, No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line No:3, No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7
使用print $NF
可以打印出一行中的最後一個字段,使用$(NF-1)
則是打印倒數第二個字段,其他以此類推:
echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $NF}'
f3
f5
echo -e "line1 f2 f3\n line2 f4 f5" | awk '{print $(NF-1)}'
f2
f4
打印每一行的第二和第三個字段:
awk '{ print $2,$3 }' filename
統計文件中的行數:
awk 'END{ print NR }' filename
以上命令只使用了END語句塊,在讀入每一行的時,awk會將NR更新爲對應的行號,當到達最後一行NR的值就是最後一行的行號,所以END語句塊中的NR就是文件的行數。
一個每一行中第一個字段值累加的例子:
seq 5 | awk 'BEGIN{ sum=0; print "總和:" } { print $1"+"; sum+=$1 } END{ print "等於"; print sum }'
總和:
1+
2+
3+
4+
5+
等於
15
將外部變量值傳遞給awk
藉助 -v
選項 ,可以將外部值(並非來自stdin)傳遞給awk:
VAR=10000
echo | awk -v VARIABLE=$VAR '{ print VARIABLE }'
另一種傳遞外部變量方法:
var1="aaa"
var2="bbb"
echo | awk '{ print v1,v2 }' v1=$var1 v2=$var2
當輸入來自於文件時使用:
awk '{ print v1,v2 }' v1=$var1 v2=$var2 filename
以上方法中,變量之間用空格分隔作爲awk的命令行參數跟隨在BEGIN、{}和END語句塊之後。
awk運算與判斷
作爲一種程序設計語言所應具有的特點之一,awk支持多種運算,這些運算與C語言提供的基本相同。awk還提供了一系列內置的運算函數(如log、sqr、cos、sin等)和一些用於對字符串進行操作(運算)的函數(如length、substr等等)。這些函數的引用大大的提高了awk的運算功能。作爲對條件轉移指令的一部分,關係判斷是每種程序設計語言都具備的功能,awk也不例外,awk中允許進行多種測試,作爲樣式匹配,還提供了模式匹配表達式(匹配)和!(不匹配)。作爲對測試的一種擴充,awk也支持用邏輯運算符。
算術運算符
運算符 | 描述 |
---|---|
+ - | 加減 |
* / & | 乘、除、求餘 |
^ *** | 求冪 |
++ -- | 增加或減少,作爲前綴或後綴 |
$ awk 'BEGIN{a=1; print a++,++a;}'
1 3
注意:所有用作算術運算符進行操作,操作數自動轉爲數值,所有非數值都變爲0
賦值運算符
運算符 | 描述 |
---|---|
= += -= *= /= %= ^= **= | 賦值語句 |
例:
a+=5; 等價於:a=a+5; 其它同類
邏輯運算符
運算符 | 描述 | ||
---|---|---|---|
` | ` | 邏輯或 | |
&& | 邏輯與 | ||
! | 邏輯非 |
例:
qinwj 14:44:47 R290-1: /mnt/X500/farmers/qinwj/test
$ awk 'BEGIN{a=1;b=5;print (a<3 && b>6),(a<3 || b>6);}'
0 1