AWK的使用簡介 awk命令的使用

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章