linux-shell編程7:awk

Awk簡介

Awk是一種編程語言,誕生於1977年,其名稱爲三位作者姓的首字母縮寫:
Alfred Aho 、Peter Weinberger 和 Brian Kernighan
awk主要用於linux/unix下對文本和數據進行掃描處理
數據可以來自標準輸入,文件,管道

awk有衆多的發行版本,awk,nawk,gawk,MKS awk,tawk包括開源產品和商業產品
目前linux中常用的swk編譯器版本mawk,gawk
rhel系統默認的爲gawk
ubuntu系列產品用mawk

此文章用gawk實現,GUN開源項目awk解釋器的開源代碼實現

Awk工作流程

首先對文件逐行掃描,從第一行到最後一行,逐行進行匹配特定模式的行,並在這些行上進行用戶想要的操作,
Awk基本結構由模式匹配和處理過程(處理動作)組成
pattern  {action}

注意:awk讀取文件每一行時,將對該行與給定的模式相匹配,如果匹配,則處理執行處理過程,否則不做任何操作,
如果沒有指定處理腳本,則把匹配的行標準輸出,默認處理動作爲print打印
如果沒有指定模式匹配,則默認匹配所有數據

Awk有倆個特殊模式,BEGIN/END,被放置在沒有讀取任何數據之前以及在所有數據讀取完成後執行

Awk的基礎語法

格式:
gawk  [選項] -f program-file  [--] file 

#選項:
-F fs, --field-separator fs
指定fs爲輸入行的分隔符(默認的分隔符爲空格或製表符)

-v var=val,--assign var=val
在執行處理動作之前,設置一個變量var值爲var

-f program-file,--file program-file
從腳本文件中讀取awk指令,以取代在命令參數中輸入腳本

-W compat,-W traditional,--compat,--traditional
使用兼容模式運行AWK,GUN拓展選項將被忽略

-W dump-variables[=file] ,--dump-variables[=file]
打印全局變量(變量名,類型,值)到文件中,
如果沒有提供文件名,則自動輸出至名爲dump-variables文件中(演示失敗)

-W copyleft ,-W copyright,--copyleft,--copyright
輸出打印簡短的GUN版本信息
  • awk程序語法結構:一個awk程序包含一系列的模式{動作指令}或者函數定義
  • 模式可以是BEGIN/END/表達式用來限定操作對象的多個表達式使用逗號隔開
  • 動作指令需要用{}引起來

案例

1。使用正則表達式匹配空行: /^$/,動作爲打印"哈哈哈哈,有空行"
[root@localhost ~]# awk '/^$/ {print "哈哈哈哈,有空行"}' quote.txt 
哈哈哈哈,有空行
哈哈哈哈,有空行
哈哈哈哈,有空行
哈哈哈哈,有空行
[root@localhost ~]# 
2.匹配包含anconda的行,並打印  /etc/syconfig/network
[root@#localhost ~]# awk '/anaconda/' /etc/sysconfig/network
# Created by anaconda
[root@#localhost ~]# 
3.利用腳本文件,判斷是否有空行
[root@#localhost ~]# cat awk1.sh 
/^$/  {print "哈哈哈哈哈哈哈啊哈哈啊"}
[root@#localhost ~]# 
[root@#localhost ~]# awk -f awk1.sh quote.txt 
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
哈哈哈哈哈哈哈啊哈哈啊
[root@#localhost ~]# 

awk操作指令

1.記錄與字段
Awk一次從文件中讀取一條記錄,並將記錄存儲在字段變量$0中,記錄被分割爲字段並存儲在$1,$2,$3………………$NF中(分隔符默認爲空格或製表符)
'NF:內建變量,記錄的字段個數'
#輸出一段話並輸出第一個字段,第二個字段,第三個字段
[root@#localhost ~]# echo I love my gril friend | awk '{print $1,$2,$3}'
I love my
[root@#localhost ~]# echo I love my gril friend | awk '{print $1,$2,$3,$5,$4}'
I love my friend gril
[root@#localhost ~]# 

#讀取輸入行數並輸出該行
[root@#localhost ~]# echo hello world | awk '{print $0,$NF}'
hello world world
[root@#localhost ~]# echo hahahhahaha | awk -F"a" '{print $NF}'

[root@#localhost ~]# echo hahahhahaha | awk -F"h" '{print $NF}'
a
[root@#localhost ~]# 

2.字段與分隔符
默認awk讀取數據以空格或製表符作爲分隔符
但可以通過-F來改變分隔符

[root@#localhost ~]# awk -F: '{print $1}' /etc/passwd
[root@#localhost ~]# awk 'BEGIN {FS=":"} {print $1}' /etc/passwd

#指定多個分割符
[root@#localhost ~]# echo 'hello the:world,!' | awk 'BEGIN {FS="[:,]"} {print $1,$2,$3,$4}'
hello the world ! 
[root@#localhost ~]#

3.內置變量
變量名稱                描述
ARGC            命令行參數個數 -v
FILENAME        當前輸入文檔的名稱
FNR             當前輸入文檔的記錄編號,多個輸入文檔時有用
'NR             輸入流當前記錄編號'
'NF             當前記錄的字段個數'
FS              字段分隔符
OFS             輸出--字段--分隔符,默認是空格
ORS             輸出--記錄--分隔符,默認換行符 \n
RS              輸入記錄分隔符,默認換行符

#示例文件
[root@#localhost ~]# cat test1.txt 
This is a test file
Welcome to Jacob's Class
[root@#localhost ~]# cat test2.txt 
Hello the world
Wow! I'm overwhelmed.
Ask for more
[root@#localhost ~]#

#輸出當前文檔的當前行編號,第一個文件倆行,第二個文件三行
[root@#localhost ~]# awk '{print FNR}' test1.txt test2.txt 

#Awk將倆個文檔作爲一個整體的輸入流,通過NR輸入當前編號
[root@#localhost ~]# awk '{print NR}' test1.txt test2.txt

[root@#localhost ~]# awk '{print $1,$2,$3,$4}' test1.txt 
This is a test
Welcome to Jacob's Class'
[root@#localhost ~]# 

#通過OFS將輸出分割符設置爲'-',print在輸出時第1,2,3個字段中間的分割符爲‘-’

[root@#localhost ~]# awk 'BEGIN {OFS="-"} {print $1,$2,$3,$4}' test1.txt 
This-is-a-test
Welcome-to-Jacob's-Class
[root@#localhost ~]#

#示例文件
[root@#localhost ~]# cat test3.txt 
mail from:[email protected]
subjectLhello
data:2018-11-12 17:00
content:Hello,The world

mail from: [email protected]
subject:congregation
data:2018-11-12 08:31
content:Congregation to you.

mail from: [email protected]
subject:Test
data:2018-11-12 10:20
content:This is a test mail
[root@#localhost ~]# 

#讀取輸入數據,以空白行爲記錄分割符,即第一個空白行前的內容爲一個記錄

 [root@#localhost ~]# awk 'BEGIN {FS="\n";RS=""} {print $2}' test3.txt 
subjectLhello
subject:congregation
subject:Test
[root@#localhost ~]# 

 4.表達式與操作
    表達式由變量,常量,函數,正則表達式,操作符組成
    awk中變量有字符和數字變量,如果在awk中定義變量沒有初始化,則初始化值爲空字符或0
    字符操作一定加引號

    #定義變量
    a='hello'
    b=12

    #操作符
    +
    -
    *
    /   除
    %   取餘
    ^   冪運算
    ++
    --
    +=
    -=
    *=
    /=
    >
    <
    >=
    <=
    ==  等於
    !=   不等於
    ~   匹配
    !~  不匹配
    &&  與
    ||  或

    #案例

    [root@#localhost ~]# echo test | awk 'x=2 {print x+3}'

    [root@#localhost ~]# echo hello | awk 'x=1,y=3 {print x*2,y*3}'
    2 9
    [root@#localhost ~]# 

    #統計所有空白行
    [root@#localhost ~]# awk '/^$/ {print x+=1}' test3.txt 
    1
    2
    [root@#localhost ~]# awk '/^$/ {x+=1} END {print x}' test3.txt 
    2
    [root@#localhost ~]# 

    #打印root用戶的UID號
    [root@#localhost ~]# awk -F: '$1~/root/ {print $3}' /etc/passwd
    0

    #打印用戶uid號大於500的用戶

    [root@#localhost ~]# awk -F: '$3>500 {print $1}' /etc/passwd
    polkitd
    unbound
    colord
    saslauth
    libstoragemgmt
    nfsnobody
    chrony
    gnome-initial-setup
    hello
    [root@#localhost ~]# 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章