歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux系統之文本格式化工具awk

Linux系統之文本格式化工具awk

日期:2017/2/28 13:54:33   编辑:Linux教程

一、文本處理工具

grep、sed和awk都是文本處理工具,雖然都是文本處理工具但卻都有各自的優缺點,一種文本處理命令是不能被另一個完全替換的,否則也不會出現三個文本處理命令了。只不過,相比較而言,sed和awk功能更強大而已,且已獨立成一種語言來介紹。

grep:文本過濾器,如果僅僅是過濾文本,可使用grep,其效率要比其他的高很多; sed:Stream EDitor,流編輯器,默認只處理模式空間,不處理原數據,如果你處理的數據是針對行進行處理的,可以使用sed;

awk:報告生成器,格式化以後顯示。如果對處理的數據需要生成報告之類的信息,或者你處理的數據是按列進行處理的,最好使用awk。

二、awk可以完成的一些功能

  • 將文本文件看做由記錄和字段組成的文本數據庫

  • 使用變量操作數據庫

  • 使用算術和字符串操作符

  • 使用普通的程序設計結構,例如循環和條件

  • 生幫格式化報告

  • 定義函數

  • 從腳本中執行unix命令

  • 處理unix命令的結果

  • 更加巧妙的處理命令行的參數

  • 更容易地處理多個輸入流

三、語法格式

1 2 # awk [options] 'script' file1 file2, ... # awk [options] 'PATTERN { action }' file1 file2, ..

1、選項

-F fs or --field-separator fs:

指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:

1 2 3 4 #awk -F: '/root/{print $1,$NF}' /etc/passwd #awk -F: '/root/{print $1$NF}' /etc/passwd #awk -F: '/root/{print $1 $NF}' /etc/passwd #awk -F: '/root/{print $1"#"$NF}' /etc/passwd

-v 選項定義的變量在腳本運行之前即存在,可以在腳本的 BEGIN 流程中被調用;

2、awk的輸出:print和printf

⑴、print的使用格式:

print item1, item2, ...

要點:

①、各項目之間使用逗號隔開,而輸出時則以空白字符分隔;

②、輸出的item可以為字符串或數值、當前記錄的字段(如$1)、變量或awk的表達式;數值會先轉換為字符串,而後再輸出;

③、print命令後面的item可以省略,此時其功能相當於print $0, 因此,如果想輸出空白行,則需要使用print "";

注意,在AWK中,$表示字段,用戶變量不需要加$,這是AWK與shell或者Perl不同之處!在shell中,變量定義時不加$,再次引用時則需要用$,而在Perl中,無論定義和引用時都需要加$ (Perl中$表示標量,另有@和%符號表示數組和Hash變量)。

實例

⑵、printf的使用格式

printf format, item1, item2, ...

format格式的指示符都以%開頭,後跟一個字符,

%c

轉換數字成ASCII,如printf "%c", 67結果為C。

%d, %i

打印十進制整數,如printf "%dn", 6.745結果為6。

%e, %E

轉換數字為科學(指數)符號,如printf "%4.3en", 6745結果為6.745e+03。

%f

以浮點表示法打印數字,如 printf "%4.3f\n", 6745結果為6745.0000000

%s

打印字符串,如printf "%10s\n", 6745結果為十個空格加6745。

可更改的格式:

N$

位置指示符,可調整字符串的輸出位置。printf "%s %s %s\n", "I", "lOVE","YOU"輸出為:I LOVE YOU,我們調整一下位置,printf "%3$s %2$s %1$s\n", "YOU", "LOVE","I",輸出結果為:I LOVE YOU

修飾符

N: 顯示寬度;

-: 左對齊; +:右對齊(也可以顯示數值符號正負之用);

3、模式和操作

⑴、模式可以是以下任意一個:

  • /正則表達式/:使用通配符的擴展集。

  • 關系表達式:可以用下面運算符表中的關系運算符進行操作,可以是字符串或數字的比較,如$2>%1選擇第二個字段比第一個字段長的行。

  • 模式匹配表達式:用運算符~(匹配)和~!(不匹配)。

  • 模式,模式:指定一個行的范圍。該語法不能包括BEGIN和END模式。

  • BEGIN:讓用戶指定在第一條輸入記錄被處理之前所發生的動作,通常可在這裡設置全局變量。

  • END:讓用戶在最後一條輸入記錄被讀取之後發生的動作。

⑵、操作由一人或多個命令、函數、表達式組成,之間由換行符或分號隔開,並位於大括號內。主要有四部份:

  • 變量或數組賦值

  • 輸出命令

  • 內置函數

  • 控制流命令

4、變量

⑴、awk內置變量之記錄變量

FS: field separator 讀取文件本時,所使用字段分隔符 RS: Record separator 輸入文本信息所使用的換行符 OFS: Output Filed Separator 輸出字段分隔符(默認值是一個空格) ORS:Output Row Separator 輸出記錄分隔符(默認值是一個換行符)

注:

從$1,$2一直到$NF,整行用$0標,如果$0被賦予新值,所有的$1,$2...和NF都將被重新計算。同樣,若$i被改變,$0將用OFS重新計算。

⑵、awk內置變量之數據變量

NR: The number of input records awk命令所處理的記錄數;如果有多個文件,這個數目會把處理的多個文件中行統一計數 NF:Number of Field 當前記錄的field個數 FNR 當前文件的相對記錄數 ARGV 數組,保存命令行本身這個字符串,如awk '{print $0}' a.txt b.txt這個命令中,ARGV[0]保存awk,ARGV[1]保存a.txt ARGC awk命令的參數的個數 FILENAME awk命令所處理的文件的名稱 ENVIRON 當前shell環境變量及其值的關聯數組

NR用法

NF用法(默認以空格分隔)

FNR用法

ARGV用法

之二

FILENAME用法

ENVIRON用法

注:

ARGV數組由ARGV[0]....ARGV[ARGC-1]組成,第一個元素是0而不是1,這與AWK中的般數組不同

ENVIROND數組在shell與AWK的交互中非常有用,使用ENVIRON["PARA_NAME"]來獲取環境變量$PARA_NAME的值,其中引號“”不可少!

5、標准輸出與重定向

⑴、輸出重定向

print items > output-file print items >> output-file print items | command ⑵、特殊文件描述符: /dev/stdin:標准輸入 /dev/sdtout: 標准輸出 /dev/stderr: 錯誤輸出 /dev/fd/N: 某特定文件描述符,如/dev/stdin就相當於/dev/fd/0;

實例:

1 2 # awk -F" " '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/issue # awk -F" " '{printf "%-15s %i\n",$1,$3 > "/dev/null" }' /etc/issue

6、awk的操作符:

⑴、算術操作符: -x: 負值 +x: 轉換為數值; x^y: x**y: 次方 x*y: 乘法 x/y:除法 x+y: x-y:

x%y:

實例

⑵、字符串操作符: 只有一個,而且不用寫出來,用於實現字符串連接; ⑶、 賦值操作符: = += -= *= /= %= ^= **= ++ --

需要注意的是,如果某模式為=號,此時使用/=/可能會有語法錯誤,應以/[=]/替代;

⑷、布爾值 awk中,任何非0值或非空字符串都為真,反之就為假; ⑸、 比較操作符: x < y True if x is less than y. x <= y True if x is less than or equal to y. x > y True if x is greater than y. x >= y True if x is greater than or equal to y. x == y True if x is equal to y. x != y True if x is not equal to y. x ~ y True if the string x matches the regexp denoted by y. x !~ y True if the string x does not match the regexp denoted by y. subscript in array True if the array array has an element with the subscript subscript. ⑺、表達式間的邏輯關系符: &&

||

實例:

⑻、條件表達式: selector?if-true-exp:if-false-exp if selector; then if-true-exp else if-false-exp fi

實例

⑼、函數調用:

function_name(para1,para2)

7、控制語句

⑴、 if-else

語法:

if (condition) {then-body} else {[ else-body ]}

實例:

1 2 3 4 #awk '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd #awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd #awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd #awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

⑵、 while

語法:

while (condition){statement1; statment2; ...}

實例:

1 2 3 4 #awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd #awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd #awk '{i=1;while (i<=NF) {if ($i>=20000) print $i; i++}}' random.txt #random.txt文件的內容為一堆隨機數。

⑶、do-while 至少執行一次循環體,不管條件滿足與否

語法:

do {statement1, statement2, ...} while (condition)

實例:

1 2 3 4 5 6 7 8 #awk 'BEGIN{ sum=0; i=0; do{ sum+=i; i++; }while(i<=100) print sum;}'

⑷、for

語法:for ( variable assignment; condition; iteration process) { statement1, statement2, ...}

實例:

1 #awk -F: '{for(i=1;i<=3;i++) { if (length($i)>=8) {print $i}}}' /etc/passwd

for循環還可以用來遍歷數組元素:

語法:

for (i in array) {statement1, statement2, ...}

實例:

1 #awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%-15s:%i\n",A,BASH[A]}}' /etc/passwd

⑸、 case

語法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...} ⑹、 break 和 continue 常用於循環或case語句中 ⑺、 next 提前結束對本行文本的處理,並接著處理下一行;例如,下面的命令將顯示其ID號為奇數的用戶:

實例:

1 # awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd

9、awk中使用數組

⑴、 數組 array[index-expression] index-expression可以使用任意字符串;需要注意的是,如果某數據組元素事先不存在,那麼在引用其時,awk會自動創建此元素並初始化為空串;因此,要判斷某數據組中是否存在某元素,需要使用index in array的方式。 要遍歷數組中的每一個元素,需要使用如下的特殊結構:

語法

for (var in array) { statement1, ... }

其中,var用於引用數組下標,而不是元素值; 實例: 1 #netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' ⑵、 刪除數組變量 從關系數組中刪除數組索引需要使用delete命令。使用格式為: delete array[index] 10、awk的內置函數 split(string, array [, fieldsep [, seps ] ]) 功能:將string表示的字符串以fieldsep為分隔符進行分隔,並將分隔後的結果保存至array為名的數組中;數組下標為從1開始的序列; 實例: 1 2 3 # netstat -ant | awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50 # netstat -tan | awk '/:80\>/{split($5,clients,":");ip[clients[4]]++}END{for(a in ip) print ip[a],a}' | sort -rn | head -50 # df -lh | awk '!/^File/{split($5,percent,"%");if(percent[1]>=20){print $1}}'

length([string])

功能:返回string字符串中字符的個數; substr(string, start [, length])

功能:取string字符串中的子串,從start開始,取length個;start從1開始計數;

1 # tail -10 /etc/passwd |awk -F: '{print substr($1,1,6)}'

system(command)

功能:執行系統command並將結果返回至awk命令

1 # awk 'BEGIN{print system("ls -l")}'

systime()

功能:systime函數返回從1970年1月1日開始到當前時間(不計閏年)的整秒數

tolower(s) 功能:將s中的所有字母轉為小寫 toupper(s) 功能:將s中的所有字母轉為大寫 1 # awk 'BEGIN{s="acl";print toupper(s)}'

================================完===================================================

PS:

awk簡單應用到此結束!

AWK簡介及使用實例 http://www.linuxidc.com/Linux/2013-12/93519.htm

AWK 簡介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htm

Shell腳本之AWK文本編輯器語法 http://www.linuxidc.com/Linux/2013-11/92787.htm

正則表達式中AWK的學習和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm

文本數據處理之AWK 圖解 http://www.linuxidc.com/Linux/2013-09/89589.htm

如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm

文本分析工具-awk http://www.linuxidc.com/Linux/2014-12/110939.htm

Copyright © Linux教程網 All Rights Reserved