Linux awk命令使用方法


  awk是linux上非常好用的文本處理工具,常用於指定列的處理,包括獲取指定列的內容、根據指定列匹配關系輸出等文本處理。本文主要描述awk命令的基本語法、正則表達式與操作符的使用、常用內置變量的含義和使用方法、內置字符串函數的使用方法。

awk基本語法

  awk [ -F 分隔符] [ -v 變量名=值 ] 'BEGING{語句} 條件類型1{動作1} 條件類型2{動作2}... END{語句}' 輸入的文件

  命令格式說明:

  (1)awk命令格式由四部分組成。選項、BEGIN、END和帶條件類型和動作的語句。這四個部分都是可選項,可省略任意部分。

  (2)-F表示設置列分隔符,默認為空格。

  (3)-v 表示初始化一個變量或者用於向awk命令傳入外部變量值,shell編程中常用。

  (4)條件類型可以是正則表達式、條件語句、復合語句以及行匹配范圍等內容。條件類型為可選設置。如果設置條件,只處理匹配條件的行執行動作。如果未設置,awk命令則認為所有行都是匹配的,並執行動作語句。動作表示執行的命令,命令必須放在大括號{}內。

  (5)必須了解這些符號。$0表示行,$1、$2、$3...$n分別表示第1列、第2列、第3列...第n列。awk命令經常會使用這些符號去做匹配、打印指定指定列等操作。

  awk命令處理流程:

  (1)執行BEGIN{} 語句塊中的內容。BEGIN語句通常用戶變量初始化、打印輸出表格的表頭。

  (2)從文件或者stdin中讀取一行。然后根據條件類型的匹配關系,判斷是否需要執行后面的動作。直到做完所有的動作和條件類型。重復這個過程,直到文件所有行處理完成。

  (3)執行END語句塊中的內容。END語句塊常用於分析匯總等統計信息,比如統計文件行數。

  基本使用實例

  下面我們通過一些基本的實例來直觀了解下awk命令的各選項和條件類型、動作的基本用法,這些實例也是awk操作或者shell編程中最常見的幾種用法。如下

  (1)$0、$1、$2、$3...$n內容

echo "2017 12 20" | awk '{print "$0="$0,"$1="$1,"$2="$2,"$3="$3}' #輸出$0=2017 12 20 $1=2017 $2=12 $3=20

  從結果輸出可以知道,$0表示整行內容,$1、$2表示執行列。print中分割字段的逗號","默認輸出為空格。如果需要輸出以逗號分隔可以用如下方式:

echo "2017 12 20" | awk '{print "$0="$0 "," "$1="$1 "," "$2="$2 "," "$3="$3}' #輸出$0=2017 12 20,$1=2017,$2=12,$3=20

(2)利用-F選項指定分隔符獲取匹配行的指定列。

echo "2017-12-20" | awk -F"-" '{print $1,$2,$3}' #獲取第1、2、3列內容,輸出2017 12 20

  如果需要考慮多個分隔符的行處理情況呢,可以通過-F '[分隔符1 分隔符2]'設置。如下一行同時包含破折號"-"、反斜干分隔符"/",獲取指定第1、2、3列內容。命令如下:

echo "2017-12/20" | awk -F"[-/]" '{print $1,$2,$3}' #輸出2017 12 20

(3)向awk命令傳入外部變量,常用於shell編程中。

var1=5 awk -v var=${var1} 'BEGIN{for(i=0;i<=var;i++)print i}' #輸出0 1 2 3 4 5

(4)BEGIN使用方法

awk 'BEGIN{num=5;for(i=0;i<=num;i++)print i}'
awk 'BEGIN{print "Begin deal with files"}' #處理文件前打印提示信息

(5)使用END語句統計文件行數。舉例如下:

awk 'END{print NR}' /etc/passwd

  說明:NR表示文件已讀取的行數,END語句塊是在文本所有行處理后執行,所以打印NR數值就是文件行數。

awk中正則表達式與條件操作符

  awk中正則表達式匹配操作中經常用到字符如下:

. * + ? $ | \ [] {} ()

  條件操作符如下:

<(小於) <=(小於等於) ==(等於) >(大於) >=(大於等於) !=(不等於) ~(匹配正則表達式) !~(不匹配正則表達式)

 其中<、>、<=等操作符用法比較簡單,這里主要講~(匹配正則表達式)、 !~(不匹配正則表達式)兩個表達式的用法。

 基本實例如下:

(1)打印第1個字段包含root字符串的行

awk -F":" '{if($1~/root/)print $0}' /etc/passwd #寫法一 awk -F":" '$1~/root/{print $0}' /etc/passwd #寫法二

(2)打印第1個字段不包含root字符串的行

awk -F":" '{if($1 !~ /root/)print $0}' /etc/passwd #寫法一 awk -F":" '$1 !~ /root/{print $0}' /etc/passwd #寫法二

(3)打印第1個字段等於root字符串的行

awk -F":" '{if($1 == "root")print $0}' /etc/passwd #寫法一 awk -F":" '$1 == "root"{print $0}' /etc/passwd #寫法二

(4)打印第1個字段不等於root字符串的行

awk -F":" '{if($1 != "root")print $0}' /etc/passwd #寫法一 awk -F":" '$1 != "root"{print $0}' /etc/passwd #寫法二

(5)打印用戶ID小於500的用戶

awk -F":" '{if($3<500)print $0}' /etc/passwd

(6)打印行首為oracle的行

awk -F":" '{if($1~/^oracle/)print $0}' /etc/passwd 

(7)打印匹配oracle或者root字符串的行

awk -F":" '{if($1~/(root|oracle)/)print $0}' /etc/passwd  #用正則表達式元字符|的方式 awk -F":" '{if($1~/root/ || $1~/oracle/)print $0}' /etc/passwd #用或||的方式

  說明:豎線符"|"表示匹配豎線"|"兩邊模式之一。使用豎線符時,語句必須用圓括號()括起來。

(8)打印同時匹配oracle和root的行

awk -F":" '{if($1=="root" && $3=="0")print $0}' /etc/passwd

awk內置變量

  awk的內置變量包括FS、NF、OFS、ORS、NR等內容,下面逐一列舉其含義和用法。

(1)FS 表示用於設置列的分隔符,與-F選項功能相同。缺省情況下為空格。舉例如下:

echo "2017-12-20" |awk 'BEGIN{FS="-"}{print $1,$2,$3}' #輸出2017 12 20

(2)NF 表示一行記錄列的總數。如果需要打印最后一列內容,舉例如下:

echo "/usr/local/bin/python" | awk -F '/' '{print $NF}' #輸出python

 說明:NF常用於打印倒數指定列的內容。

  如打印指定列到最后一列的內容,方法如下:

 

awk -F " "  '{for (i=4;i<=NF;i++)printf("%s ", $i);print ""}' file.txt

 

(3)OFS 表示指定輸出字段分隔符,缺省為空格。舉例如下:

echo "1990 09 09" | awk 'BEGIN{OFS="-"}{print $1,$2,$3}' #輸出1990-09-09

(4)ORS 表示輸出行記錄的分隔符,默認為換行符(\n)。如果需要設置輸出行的分隔符為#,可以如下表示:

echo -e "1990\n09\n09" | awk 'BEGIN{ORS="#"}{print $0}' #輸出1990#09#09#

(5)NR 表示已讀的記錄數。如果需要打印文件行數,舉例如下:

awk 'END{print NR}' /etc/passwd

(6)FILENAME 表示當前處理文件名。舉例如下:

awk 'END{print FILENAME}' /etc/passwd

awk內置字符串函數

(1)length(string) 返回計算字符串string的長度。舉例如下:

echo "Hello World" | awk '{print length($0)}' #輸出11

(2)index(string,substr)  返回待查找字符substr在字符串string中的位置,其中substr必須用雙引號將字符串括起來。舉例如下:

echo "Hello World" | awk '{print index($0,"o")}' #輸出5 awk 'BEGIN{print index("Hello World","o")}' #輸出5

(3)match(string,regex)  檢查正則表達式regex是否能夠匹配字符串,如果匹配返回值為非0,如果未匹配,返回0。舉例如下:

awk 'BEGIN{print match("Hello World",'o')}' #查找字符串o第一次出現的位置,輸出1 echo "Hello World" | awk '{print match($0,'o')}' #同上,輸出1 awk 'BEGIN{print match("Hello World",/[Oo]/)}' #查找字符串大寫或小寫o第一次出現的位置。輸出5

 (4)split(string,array,delimeter)  使用指定的分隔符delimeter分割字符串string,並將分割出的結果保存到arayr數組。split()函數返回值為數組長度。舉例如下:

echo "123#456#789" | awk '{len=split($0,arr,"#");for(i=1;i<=len;i++)print arr[i]}' 

  說明:通過獲取到的數組長度,通過循環方式獲取數組中的內容,其中數組下標是從1開始計算。更為簡便的獲取方法如下:

echo "123#456#789" | awk '{split($0,arr,"#");for(i in arr)print arr[i]}' 

(5)sub(regex,string)  表示用字符串string替換正則表達式regex匹配的內容。舉例如下:

echo "Java:Python:Java:C" | awk 'sub(/Java/,"Ruby",$0)' #輸出Ruby:Python:Java:C

(6)substr(string,pos) 獲取字符串sting中從指定位置pos后的內容。舉例如下

echo "Java:Python:C" | awk '{print substr($0,6)}' #輸出Python:C

(7)substr(string,pos,n)  獲取字符串string中從指定位置pos開始長度為n的內容

echo "Java:Python:C" | awk '{print substr($0,1,4)}' #輸出Java

(8)gsub(regex,string) 表示使用字符串string替換正則表達式regex匹配的內容。舉例如下:

echo "Java:Python:Java:C" | awk 'gsub(/Java/,"Ruby")' #輸出Ruby:Python:Ruby:C

(9)gsub(regex,string,target) 表示在指定的范圍內,使用字符串string替換正則表達式regex匹配的內容。舉例如下:

echo "Learn Shell at 2013-08-08" | awk 'gsub(/-/,":",$4)' #輸出Learn Shell at 2013:08:08

awk內置算術函數

 這里主要介紹int()、srand()、rand()3個算術函數。

(1)int(x) 返回x的整數

awk 'BEGIN{i=3.1415926;print int(i)}' #輸出3

(2)rand() 返回0~1的任意數字。

awk 'BEGIN{srand();num=rand();print num}' #輸出0~1的任意值,每執行一次變化一次。

 說明:如果不加上srand()函數,每次執行打印的值都相同。

awk內容打印(printf&print)

 awk可以使用print和printf輸出字符串。主要區別是printf可以自定義輸出的模式,輸出內容后不換行。print輸出內容后會自動換行。

printf使用格式:

(1)printf([格式控制符],參數)

(2) printf [格式控制符],參數

格式(1)和(2)的區別就是帶不帶小括號。個人覺得帶小括號更直觀。畢竟是個函數。下面這說明一下printf格式控制符中的常用格式修飾符

常用格式:%d表示整數、%s表示字符串。

修飾符:破折號"-"表示左對齊、Width表示步長。

printf基本使用實例

(1)格式化輸出字符串

$ echo -e "12345 678\n123456788 890" | awk '{printf("%-11d %-5d\n",$1,$2)}' $ echo -e "12345 678\n123456788 890" | awk '{printf"%-11d %-5d\n",$1,$2}' #不帶小括號

 如果使用print函數的話,就可以自動換行了,不需要手工添加換行符。同樣,print也是可以帶小括號。

$ echo -e "12345 678\n123456788 890" | awk '{print $1,$2}'

(2)利用printf生成數據。使用方法如下

$ awk 'BEGIN{data_format="136%03d\n";for(i=0;i<=3;i++)printf(data_format,i)}'

小結

  本文內容介紹了awk命令的基本語法和常用實例。awk具有強大的文本處理能力,掌握awk命令的基本內容可以完成工作上遇到的大部分問題。另外,awk構造大批量測試數據有非常高的效率。


免責聲明!

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



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