天天看點

Linux文本處理指令-awk1.awk标準文法格式2.awk變量3.awk數組4.awk循環5.awk函數6.常見示例:

awk文法及示例

  • 1.awk标準文法格式
  • 2.awk變量
  • 3.awk數組
  • 4.awk循環
  • 5.awk函數
  • 6.常見示例:

1.awk标準文法格式

awk其名稱得自于它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。在比較複雜的shell腳本中經常用到,awk grep sed三個合起來,被俗稱為shell三劍客。它是linux系統很強大的文本處理指令,并且友善生成各種報表,文法借鑒了C語言。awk同樣支援處理檔案和标準輸入的内容。

awk最完整的書寫格式如下:

awk 'BEGING{command1}{command2}END{command3}' file_name
           
其中BEGING和END不是必須的,這裡保留了。

awk簡化版的格式如下:

awk '{command2}' file_name
           
其中BEGING和END不是必須的,這裡省略了。.

一個簡單完整的例子

[[email protected] awk]# awk 'BEGIN{print"star"}{print $1}END{print "end"}' ips
star
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
end
[[email protected] awk]#
           
BEGIN在腳本運作前執行一次,逐行讀入檔案的第1列并列印出來,END在腳本運作後執行一次,

一個簡化版的例子

[[email protected] awk]# awk '{print $1}' ips
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
[[email protected] awk]#
           
逐行讀入檔案的第1列并列印出來。

如果要一次在一行列印多個變量,使用逗号

[[email protected] awk]# awk '{print $1,"hello","world"}' ips
10.100.12.11 hello world
10.100.12.12 hello world
10.100.12.89 hello world
10.100.12.9 hello world
10.100.13.8 hello world
10.100.12.11 hello world
[[email protected] awk]#
           
awk會自動用空格分隔不同的變量。

如果要一次執行多個指令,并且不在一行顯示,使用分号

[[email protected] awk]# awk '{print $1;print "hello";print "world"}' ips
10.100.12.11
hello
world
10.100.12.12
hello
world
10.100.12.89
hello
world
10.100.12.9
hello
world
10.100.13.8
hello
world
10.100.12.11
hello
world
[[email protected] awk]#
           
每次讀入一行後,三條指令執行一遍。

2.awk變量

awk也是一門功能完整的程式設計語言,是以在各種unix類系統都自帶它。awk的變量主要分為内置變量和自定義變量。

以下是常見的内置變量:

$0	目前記錄(作為單個變量)
$1~$n	目前記錄的第n個字段,字段間由FS分隔
FS	輸入字段分隔符 預設是空格
NF	目前記錄中的字段個數,就是有多少列
NR	已經讀出的記錄數,就是行号,從1開始
RS	輸入的記錄他隔符默 認為換行符
OFS	輸出字段分隔符 預設也是空格
ORS	輸出的記錄分隔符,預設為換行符
ARGC	指令行參數個數
ARGV	指令行參數數組
FILENAME	目前輸入檔案的名字
IGNORECASE	如果為真,則進行忽略大小寫的比對
ARGIND	目前被處理檔案的ARGV标志符
CONVFMT	數字轉換格式 %.6g
ENVIRON	UNIX環境變量
ERRNO	UNIX系統錯誤消息
FIELDWIDTHS	輸入字段寬度的空白分隔字元串
FNR	目前記錄數
OFMT	數字的輸出格式 %.6g
RSTART	被比對函數比對的字元串首
RLENGTH	被比對函數比對的字元串長度
SUBSEP	\034
           

自定義變量的使用:

awk像python一樣,變量可以不用定義直接使用。

[[email protected] awk]# awk '{print $1;a=NR;print a}' ips
10.100.12.11
1
10.100.12.12
2
10.100.12.89
3
10.100.12.9
4
10.100.13.8
5
10.100.12.11
6
           
這裡把内置變量NR的值賦給了a,并且再列印a,這裡隻說明如何定義和使用變量。
[[email protected] awk]# awk 'BEGIN{name="robin"}{print $1;a++}END{print a,name}' ips
10.100.12.11
10.100.12.12
10.100.12.89
10.100.12.9
10.100.13.8
10.100.12.11
6 robin
[[email protected] awk]#
           
經過這個測試我們發現,前面定義的變量name和中間定義的變量a,在END部分都可用直接引用。

3.awk數組

假設現在有一個需求,我們拿到了好多IP位址,想快速計算出出現次數前3的IP位址。

使用awk的數組實作

[[email protected] awk]# awk '{ip[$1]++}END{for(i in ip)print(i,ip[i])}' ips|sort|head -n 3
10.100.12.11 2
10.100.12.12 1
10.100.12.89 1
[[email protected] awk]#
           

使用awk、sort、uniq實作

[[email protected] awk]# awk '{print $1}' ips|sort|uniq -c|head -n 3
      2 10.100.12.11
      1 10.100.12.12
      1 10.100.12.89
[[email protected] awk]#
           

4.awk循環

待續

5.awk函數

待續

6.常見示例:

example1 分列顯示文本檔案内容, $0所有列,$1第一列,$2第二列

[[email protected] linux-shell-test]# awk '{ print $0 }' awk.sh
hello robin
nihao huanhuan
byby joe
[[email protected] linux-shell-test]# awk '{ print $1 }' awk.sh
hello
nihao
byby
[[email protected] linux-shell-test]# awk '{ print $2 }' awk.sh
robin
huanhuan
joe
           

example2 分列顯示标準輸入文本

[[email protected] linux-shell-test]# ps -ef|grep python|awk '{ print $0 }'
root       803     1  0 Feb28 ?        00:00:43 /usr/bin/python -Es /usr/sbin/tuned -l -P
root      6820  6216  0 23:21 pts/0    00:00:00 grep --color=auto python
root     19785     1  0 Feb29 ?        00:00:50 python proxyserver.py 11081
[[email protected] linux-shell-test]# ps -ef|grep python|awk '{ print $2 }'
803
6828
19785
           

example3 使用自定義分隔符分列顯示文本,-F ‘=’

[[email protected] linux-shell-test]# awk -F '=' '{print $0 }' awk.sh
hello robin
nihao huanhuan
byby joe
name1=robin
name2=joe
age1=22
[[email protected] linux-shell-test]# awk -F '=' '{print $1 }' awk.sh
hello robin
nihao huanhuan
byby joe
name1
name2
age1
[[email protected] linux-shell-test]# awk -F '=' '{print $2 }' awk.sh



robin
joe
22
           

example4 分列後顯示前N行,NR<=3

[[email protected] linux-shell-test]# awk  'NR<=3 { print $2 }' awk.sh
robin
huanhuan
joe
           

example5 讀取shell中變量,用于awk指令參數

[[email protected] linux-shell-test]# awk -v var=$split_char -F '=' 'NR<=6 { print $1 var }' awk.sh
hello robin=
nihao huanhuan=
byby joe=
name1=
name2=
age1=
           

example6 拆分标準輸入或者檔案内容,并重新格式化

[[email protected] linux-shell-test]# echo -e 'line1=hello\nline2=world'|awk -F '=' '{ print $1": "$2 }'
line1: hello
line2: world
[[email protected] linux-shell-test]# awk -F '=' 'NR>3 { print $1": "$2 }' awk.sh
name1: robin
name2: joe
age1: 22
           

example7 awk也算是一個程式設計語言,我們先把簡單的、最常用的使用方式搞清除了,再來嘗試進階的使用。

請打開後自行學習 https://awk.readthedocs.io/en/latest/index.html
           

繼續閱讀