shell命令之awk

一、awk簡介

awk 是一種編程語言,用于在linux/unix下對文本和數(shù)據(jù)進行處理。
數(shù)據(jù)可以來自標準輸入、一個或多個文件,或其它命令的輸出。
支持用戶自定義函數(shù)和動態(tài)正則表達式等先進功能,是linux/unix
下的一個強大編程工具。
在命令行中使用,但更多是作為腳本來使用。
awk的處理文本和數(shù)據(jù)的方式是這樣的,它逐行掃描文件,從第一行到最后一行,尋找匹配的特定模式的行,并在這些行上進行你想要的操作。如果沒有指定處理動作,則把匹配的行顯示到標準輸出(屏幕),如果沒有指定模式,則所有被操作所指定的行都被處理。
awk分別代表其作者姓氏的第一個字母。因為它的作者是三個人,分別是Alfred Aho、Brian Kernighan、Peter Weinberger。
gawk是awk的GNU版本,它提供了Bell實驗室和GNU的一些擴展。
二、awk的兩種形式語法格式

awk [options] 'commands' filenames
awk [options] -f awk-script-file filanames

options:
-F對于每次處理的內容,可以指定一個子定義的分隔符,默認的分隔符是空白字符(空格或 tab 鍵 )
command:

BEGIN{}                        {}               END{}

處理所有內容之前的動作       處理內容中的動作   處理所有內容之后的動作

示例

 awk 'BEGIN{print "----開始處理了---"} {print "ok"} END{print "----都處理完畢---"}' /etc/hosts
----開始處理了---
ok
ok
ok
----都處理完畢---

BEGIN{}通常用于定義一些變量,例如BEGIN{FS=":";OFS="---"}

三、awk工作原理

awk -F: '{print $1,$3}' /etc/passwd
(1)awk,會處理文件的每一個行,每次處理時,使用一行作為輸入,并將這一行賦給內部變量$0,每一行也可稱為一個記錄,以換行符結束。
(2)然后,行被:(默認為空格或制表符)分解成字段(或稱為域),每個字段存儲在已編號的變量中,從$1開始,最多達100個字段。
(3)awk如何知道用空白字符來分隔字段的呢? 因為有一個內部變量FS來確定字段分隔符。初始時,F(xiàn)S賦為空白字符。
(4)awk打印字段時,將以內置的方法使用 print 函數(shù)打印,awk 在打印出的字段間加上空格。這個空格是內部的一個變量 OFS 輸出字段的分隔符, 逗號 , 會和 OFS 進行映射,通過 OFS 可以控制這個輸出分隔符的值。
(5)awk輸出之后,將從文件中獲取另一行,并將其存儲在$0中,覆蓋原來的內容,然后將新的字符串分隔成字段并進行處理。該過程將持續(xù)到所有行處理完畢。
==============================================================

四、記錄與字段相關內部變量

$0 :awk變量 $0 保存當前正在處理的行內容
NR :當前正在處理的行是 awk 總共處理的行號。
FNR:當前正在處理的行在其文件中的行號。
NF :每行被處理時的總字段數(shù)
FS :輸入行時的字段分隔符,默認空格

awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
以:作分隔符,取第1部分和第3部分

OFS: 輸出字段分隔符,默認是一個 空格

awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2,$3,$4}' /etc/passwd
以:做分隔符,+++代替空格連接字段,輸出1、2、3、4部分

ORS輸出記錄分隔符, 默認是換行符.

示例

將文件每一行合并為一行(將ORS的默認輸出換行符\n改成空格 )

awk 'BEGIN{ORS="  "} {print $0}' /etc/passwd 

五、格式化輸出

printf 函數(shù)
awk -F: '{printf "%-15s %-10s %-15s\n", $1,$2,$3}' /etc/passwd
以:作分隔符,左對齊輸出1、2、3部分,且1、3部分長15個字符,2部分長10個字符
awk -F: '{printf "|%-15s| %-10s| %-15s|\n", $1,$2,$3}' /etc/passwd
同上,只是中間多了 | 做分隔

%s字符類型
%d 十進制整數(shù)
%f浮點類型
%-15s占15字符 - 表示左對齊,默認是右對齊
printf 默認不會在行尾自動換行,加 \n

六、awk模式和動作

任何 awk 語句都由 模式 和 動作 組成。
模式部分 決定動作語句何時觸發(fā)及觸發(fā)事件。
如果省略模式部分,動作將時刻保持執(zhí)行狀態(tài)。
模式可以是任何條件語句或復合語句或正則表達式。

模式可以是

正則表達式:(正則表達式需要寫在//中)

匹配記錄(整行的匹配):
awk '/^root/' /etc/passwd #root開頭的行
awk '$0 ~ /^root/' /etc/passwd #root開頭的行
awk '!/root/' passwd #不帶有root的行
awk '$0 !~ /^root/' /etc/passwd #不以root開頭的行
匹配字段:可以使用的匹配操作符(~!~
awk -F: '$1 ~ /^alice/' /etc/passwd #$1中alice開頭的行
awk -F: '$NF !~ /bash$/' /etc/passwd #最后一個字段不是bash結尾的行
比較表達式:

比較表達式采用對文本進行比較,只有當條件為真,才執(zhí)行指定的動作。
比較表達式使用關系運算符,用于比較數(shù)字與字符串。

關系運算符有

< 小于 例如 x<y
> 大于 x>y
<= 小于或等于 x<=y
== 等于 x==y
!= 不等于 x!=y
>= 大于等于 x>=y

示例
awk -F: '$3 == 0' /etc/passwd
awk -F: '$3 < 10' /etc/passwd 
awk -F: '$NF == "/bin/bash"' /etc/passwd
awk -F: '$1 == "root"' /etc/passwd

df -P | grep '/' |awk '$4 > 25000'
條件表達式:
awk -F: '$3>300 {print $0}' /etc/passwd
awk -F: '{ if($3>300) print $0 }' /etc/passwd
awk -F: '{ if($3>300) {print $0} }' /etc/passwd
awk -F: '{ if($3>300) {print $3} else{print $1} }' /etc/passwd
算術運算:+ - * / %(模-取余) ^(冪)

可以在模式中執(zhí)行計算,awk都將按浮點數(shù)方式執(zhí)行算術運算

awk -F: '$3 * 10 > 500' /etc/passwd
awk -F: '{ if($3*10>500){print $0} }' /etc/passwd
邏輯操作符合復合模式

&&邏輯與,相當于并且
||邏輯或,相當于或者
!邏輯非,取反

awk -F: '$1~/root/ && $3<=15' /etc/passwd
awk -F: '$1~/root/ || $3<=15' /etc/passwd
awk -F: '!($1~/root/ || $3<=15)' /etc/passwd
范圍模式, 模式之間用逗號 , 隔開

使用語法是:起始表達式,終止表達式

下面例子的意思是:從開頭是bin的行開始匹配成功一直到含有adm的行結束匹配
也就是 開頭是bin的行到含有adm的行的所有內容都符合匹配條件

awk -F: '/^bin/,/adm/ {print $0 }' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
awk 正則示例:

匹配開頭是bin的或者開頭是root的行

awk -F: '/^(bin|root)/' /etc/passwd
root:x:0:0:root:/root:/bin/zsh
bin:x:1:1:bin:/bin:/sbin/nologin
指定多個分隔符:[]
echo "a b|c d| ||||e | |" |awk -F'[ |]' '{print $10}'。
e
echo "a b|c d| ||||e | |" |awk -F'[ |]' '{print $10}'
e

注意:在正則中,中括號[]內的任意字符均視為普通字符,比如. *都被當做普通字符。

echo "a.b*c" |awk -F'[.*]' '{print $1, $2,$3}'
a b c

七、awk的腳本編程

條件判斷

if語句
awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd

awk -F: '{ if($3==0){count++} else{i++} } END{print "管理員個數(shù): "count "系統(tǒng)用戶數(shù): "i}' /etc/passwd
輸入:
管理員個數(shù): 1系統(tǒng)用戶數(shù): 24

awk -F: '{ if($3==0){count++} else{i++} } END{print "管理員個數(shù): "count ; print  "系統(tǒng)用戶數(shù): "i}' /etc/passwd
輸出:
管理員個數(shù): 1
系統(tǒng)用戶數(shù): 24
if...else if...else 語句
awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i; print k; print j}' /etc/passwd
輸出:
1
2
22

awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理員個數(shù): "i; print "普通用個數(shù): "k; print "系統(tǒng)用戶: "j}' /etc/passwd
輸出:
管理員個數(shù): 1
普通用個數(shù): 2
系統(tǒng)用戶: 22

awk使用外部變量

擴展
方法一:awk 參數(shù) -v (推薦使用,易讀)

[root@tianyun ~]# echo "unix script" |awk -v var="bash" 'gsub(/unix/,var)'
bash script

[root@tianyun ~]# awk -v user=root -F: '$1 == **user**' /etc/passwd
root:x:0:0:root:/root:/bin/bash

gsub 使 AWK 中的內置函數(shù),功能使搜索替換
'gsub(/unix/,var) 中的意思是搜索 unix 字符串,替換為 var 變量對應的值

方法二:在雙引號的情況下使用

[root@tianyun ~]# var="bash"
[root@tianyun ~]# echo "unix script" |awk "gsub(/unix/,\"$var\")"
bash script

方法三:在單引號的情況下使用(逼不得已使用)

[root@tianyun ~]# var="bash"
[root@tianyun ~]# echo "unix script" |awk 'gsub(/unix/,"'"$var"'")'
bash script

其他練習

root@tianyun ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/cl-root 2.8T 246G 2.5T 9% /
tmpfs 24G 20K 24G 1% /dev/shm
/dev/sda2 1014M 194M 821M 20% /boot

[root@tianyun ~]# df -h |awk '{ if(int($5)>5){print $6":"$5} }'
/:9%
/boot:20%

[root@tianyun ~]# i=10
[root@tianyun ~]# df -h |awk '{ if(int($5)>'''$i'''){print $6":"$5} }'
/boot:20%

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • grep grep的基本用法 grep命令是支持正則表達式的一個多用途文本搜索工具,一般格式為 grep 選項 模...
    王詩翔閱讀 3,548評論 2 34
  • 一、awk簡介 awk 是一種編程語言,用于在linux/unix下對文本和數(shù)據(jù)進行處理。 數(shù)據(jù)可以來自標準輸入、...
    沙礫丶ye閱讀 198評論 0 0
  • 一.基本介紹 1.awk: awk是一個強大的文本分析工具,在對文本文件的處理以及生成報表,awk是無可替代的。a...
    大福技術閱讀 1,741評論 1 4
  • 一、awk簡介 awk 是一種編程語言,用于在linux/unix下對文本和數(shù)據(jù)進行處理。 數(shù)據(jù)可以來自標準輸入、...
    休止符的嘆息閱讀 152評論 0 0
  • 一、awk簡介 awk其名稱得自于它的創(chuàng)始人 Alfred Aho 、Peter Weinberger 和 Bri...
    鐘離惜閱讀 5,374評論 0 2

友情鏈接更多精彩內容