awk命令的使用

一、簡介

awk命令是一種編程語言,用于在linux/unix下對文本和數據進行掃描和處理的工具,其數據來源可以為標準輸入、文件、管道等等。awk命令會從第一行輸入開始逐行掃描至最后一行,尋找其中匹配特定模式的行,并在相應的行上執行用戶指定的操作。Awk命令的基本架構由模式匹配和處理動作組成,默認處理動作為print打印行。

二、awk命令的使用

1、命令格式

gawk [options] 'program...' FILE ...

2、常見選項

-F fs:指明字段分隔符;
-v var=value:自定義變量;
-f programfile:從文件中讀取program命令;

3、program語句

其program語句的常見格式為:PATTERN{action,statements},其中多個program語句之間通過;分隔。

  • 其中PATTERN格式為:
    1)empty:空模式,表示匹配每一行,如:awk -F: '{print $1,$3}' /etc/passwd 表示以:為分隔符,打印每行的第一和第三個字段 。
    2)/regular expression/:僅處理能夠被此模式匹配到的行,如:awk -F: '/^root/{print $1,$3}' /etc/passwd,表示以:為分隔符,打印以root開頭的行的第一和第三個字段;
    3)/PATTERN1/,/PATTERN2/:表示僅處理從第一個被pattern1匹配到行,到第一個被pattern2所匹配的行之間的所有行,如:awk -F: '/root/,/shutdown/{print $1,$3}' /etc/passwd,表示以:為分隔符,打印從第一個以root開頭的行到第一個以shutdown開頭的行之間的所有行的第一和第三個字段。
    4)relation expression:使用關系表達式進行匹配,只有結果會真的行才會被處理,如:awk -F: '(NR>=10&&NR<=20){print $1,$3}' /etc/passwd,表示以:為分隔符,打印10-20行的第一和第三個字段;
    5)BEGIN{}和END{}
    BEGIN{}:表示在開始處理行前執行一次指定的操作;
    END{}:表示在結束對行的處理后執行一次指定的操作;
    如:awk -F: 'BEGIN{print "This is the begin."};{print $1,$3};END{print "This is the end."}' /etc/passwd,表示在執行行打印操作前,先打印指定的字符串"This is the begin.",在執行行打印操作后再打印字符串“This is the end.”
  • program語句的變量
    program中內置了一些變量,在編寫program語句時能夠直接調用相應的變量,進而簡化語句。調用內建變量時無需加$。

FS:輸入字段分隔符,默認為空白字符;
OFS:輸出字段分隔符,默認為空白字符;
RS:輸入時的換行符;
ORS:輸出時的換行符;
NF:每行的字段數,$NF表示最后一個字段;
NR:表示行數;
FNR:若提供多個文件,則分別計算各文件的行數;
FILENAME:當前文件名;
ARGC:命令行參數的個數;
ARGV:參數數組,保存的是命令行給定的各參數;

另外也可以在awk命令中自定義相關的變量,可以使用-v選項自定義變量,也可以在語句當中進行賦值操作,如:awk 'BEGIN{test="hello awk"; print test}'、ls -l | awk '/root/{hello="this is a test.";print $3,hello}'

  • action
    常見的action動作有:print、printf
    1)print命令
    其使用格式類似于print item1,item2,...,使用逗號作為分隔符,輸出的item可以為字符串,也可以為數值,也可以為當前記錄的字段、變量或表達式等。如果省略了item,則相當于print $0打印所有行。
    2)printf命令
    printf命令常用于格式化輸出awk命令的執行結果信息。其格式類似于printf FORMAT,item1,item2...,其中必須指定FORMAT格式;如需換行,需手動添加\n換行符;在FORMAT中需要分別為后面的每個item指定一個格式符。
    其對應的格式符有:

%c: 顯示字符的ASCII碼;
%d, %i: 顯示十進制整數;
%e, %E: 科學計數法數值顯示;
%f:顯示為浮點數;
%g, %G:以科學計數法或浮點形式顯示數值;
%s:顯示字符串;
%u:無符號整數;
%%: 顯示%自身

其中還可以使用以下修飾符對格式符進行輸出格式的整理:

#[.#]:第一個#數字控制格式符顯示的寬度;第二個#數字表示格式符顯示的內容的精確度,只顯示最大長度為#的格式符內容;
-:左對齊,默認為右對齊;
+:顯示數值的符號;

如下示例:

[root@localhost ~]# awk -F: '{printf "The user:%-20s User ID:%15d\n",$1,$3} ' /etc/passwd
The user:root                 User ID:              0
The user:bin                  User ID:              1
The user:daemon               User ID:              2
The user:adm                  User ID:              3
The user:lp                   User ID:              4
The user:sync                 User ID:              5
The user:shutdown             User ID:              6
The user:halt                 User ID:              7
The user:mail                 User ID:              8
The user:operator             User ID:             11
The user:games                User ID:             12
The user:ftp                  User ID:             14
The user:nobody               User ID:             99
The user:avahi-autoipd        User ID:            170
The user:systemd-bus-proxy    User ID:            999
The user:systemd-network      User ID:            998
The user:dbus                 User ID:             81
The user:polkitd              User ID:            997
The user:tss                  User ID:             59
The user:postfix              User ID:             89
The user:sshd                 User ID:             74
  • 條件表達式
    awk命令的program語句也支持通過條件表達式來判斷控制,其表達式支持常見的算術、賦值、比較等操作符,如:+,-,*,/,%,=,+=,>,<,~等等的操作符,也支持邏輯操作與或非,其格式為:

awk [optioins] '{selector?if-true-expression:if-false-expression;action statements}' /PATH/TO/SOMEFILE

如根據用戶ID判斷對應用戶是系統用戶還是普通用戶:

[root@localhost ~]# awk -F:  '{$3>=1000?usertype="this is a common user.":usertype="This is a system user.";printf "%20s:%-s\n",$1,usertype}' /etc/passwd
                root:This is a system user.
                 bin:This is a system user.
              daemon:This is a system user.
                 adm:This is a system user.
                  lp:This is a system user.
                sync:This is a system user.
            shutdown:This is a system user.
                halt:This is a system user.
                mail:This is a system user.
            operator:This is a system user.
               games:This is a system user.
                 ftp:This is a system user.
              nobody:This is a system user.
             pegasus:This is a system user.
       avahi-autoipd:This is a system user.
                 ods:This is a system user.
   systemd-bus-proxy:This is a system user.
     systemd-network:This is a system user.
                dbus:This is a system user.
             polkitd:This is a system user.
                sssd:This is a system user.
              apache:This is a system user.

三、使用案例

  • 格式化打印當前系統的用戶列表
[root@localhost ~]# awk -F: 'BEGIN{print "User lists"};{printf "User:%-25s\n",$1};END{print "This is the end."}' /etc/passwd
User lists
User:root                     
User:bin                      
.....  
User:nologin                  
User:hadoop                   
This is the end.
[root@localhost ~]# 
  • 搜索打印以/bin/bash為默認shell的用戶信息:
[root@localhost ~]# awk -F: '$7~/.*bash\>/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
amandabackup:x:33:6:Amanda user:/var/lib/amanda:/bin/bash
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
centos:x:1001:1001::/home/centos:/bin/bash
federo:x:1002:1002::/home/federo:/bin/bash
counter:x:1003:1004::/home/counter:/bin/bash
charlie:x:1004:1005::/home/charlie:/bin/bash
Jone:x:1006:1007::/Jone:/bin/bash
Williom:x:1200:1005::/home/Williom:/bin/bash
mageia:x:1100:1100::/home/linux:/bin/bash
bash:x:2003:2003::/home/bash:/bin/bash
testbash:x:2004:2004::/home/testbash:/bin/bash
basher:x:2005:2005::/home/basher:/bin/bash
hadoop:x:2007:2007::/home/hadoop:/bin/bash
  • 獲取系統網卡的Ip地址
[root@localhost ~]# ifconfig | awk '/inet\>/{print $2}'
188.88.88.42
127.0.0.1
192.168.122.1
  • 對比兩個文件的內容
[root@localhost tmp]# cat a.sh 
hello,world
i am charlie
this is my linux
magedeu
[root@localhost tmp]# cat b.sh 
1
hello,world
2
i am charlie
3
this is my linux
4
magedeu
[root@localhost tmp]# awk 'FNR==NR{a[$0];next}{if($0 in a)print $0}' a.sh b.sh
hello,world
i am charlie
this is my linux
magedeu

上述awk命令在FNR和NR的等式成立的時候,將文件a.sh每行的內容作為數組a下標,然后執行next跳過后續if判斷語句;當FNR和NR的等式不成立的時候,不執行a[$0];next,執行后面的if語句,判斷b.sh中的每行內容是否為a數組中的元素下標,是的話就打印該行信息。

同理,利用取反找出不同的行:

[root@localhost tmp]# awk 'FNR==NR{a[$0];next}{if (!($0 in a))print $0}' a.sh b.sh
1
2
3
4
  • 從文件中讀取program語句執行awk命令
    這里以上面文件對比的命令為例:
[root@localhost tmp]# cat awk.sh 
FNR==NR{
    a[$0];
    next
}
{
    if (!($0 in a))
    print $0
}
[root@localhost tmp]# awk -f awk.sh a.sh b.sh
1
2
3
4

如有錯誤,歡迎指點~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉載 原文的排版和內容都更加友好,并且詳細,我只是在這里貼出了一部分留作自己以后參考和學習,如希望更詳細了解AWK...
    XKirk閱讀 3,254評論 2 25
  • awk介紹awk變量printf命令:實現格式化輸出操作符awk patternawk actionawk數組aw...
    哈嘍別樣閱讀 1,588評論 0 4
  • 本章主要學習內容awk介紹 ?awk基本用法 ?awk變量 ?awk格式化 ?awk操作符 ?awk條件判斷 ?a...
    楠人幫閱讀 1,286評論 0 8
  • awk: grep,sed,awk grep:文本過濾 sed:文本編輯 awk:文本格式化工具; 1 什么是aw...
    木林森閱讀 1,809評論 0 16
  • awk:報告生成器,格式化文本輸出 內容: awk介紹 awk基本用法 awk變量 awk格式化 awk操作符 a...
    BossHuang閱讀 1,468評論 0 9