Linux 中的 awk 命令

AWK 是 Linux 中最強大的命令之一。 您可以使用 awk 命令管理數據並生成報告。 它還允許我們使用邏輯運算、變量、打印函數等等。 AWK 代表“Aho、Weinberger 和 Kernighan”,主要用於模式掃描和處理。 它搜索一個或多個文件以查看它們是否包含與指定模式匹配的行,然後執行相關操作。 它從文件或從其標準輸入中讀取並輸出到其標準輸出。 對於每一行,它以給定的順序與給定的模式匹配,如果匹配則執行相應的操作。

特徵

• 以記錄和字段的形式查看文本文件
• 它有變量、條件和循環
• 具有算術和字符串運算符
• 可以生成格式化報告
• 從字符串或文件中讀取和編輯文本

在本教程中,我們將通過示例來研究 AWK Linux 命令,看看它可以做什麼。

AWK 的 Basix 語法

AWK 命令的基本語法如下所示:

awk options program input-file

每個選項的簡要說明如下所示:

• -F fs:用於指定文件分隔符。
• -f 文件:用於指定包含awk 腳本的文件。
• -v var=value :用於聲明變量。

我們將使用以下文本文件作為本文所有示例的輸入文件:

cat > contents.txt

hitesh engineer sales 30000
jayesh director account 25000
vyom manager purchase 20000
bhavesh engineer sales 30000
rajesh directory sales 40000
niraj clerk account 20000
jay peon purchase 23000
deep clerk sales 20000

現在,讓我們使用 AWK 命令檢查名為“contents.txt”的文件的內容:

awk '{print}' contents.txt

這將打印文件的內容,如下所示:

hitesh engineer sales 30000
jayesh director account 25000
vyom manager purchase 20000
bhavesh engineer sales 30000
rajesh directory sales 40000
niraj clerk account 20000
jay peon purchase 23000
deep clerk sales 20000

在上面 example, 沒有給出模式,所以它將打印整個文件。

現在,打印與模式“sales”匹配的所有行:

awk '/sales/ {print}' contents.txt

這將打印包含單詞“sales”的所有行,如下所示:

hitesh engineer sales 30000
bhavesh engineer sales 30000
rajesh directory sales 40000
deep clerk sales 20000

AWK 中的變量

AWK 帶有一些內置變量,用於將一行文本分成稱為字段的單個單詞或片段。 其中一些如下所示:

• $0 :用於整行。
• $1 :用於第一個字段。
• $2 :用於第二個字段。
• $n :用於第n 個字段。
• NR:用於指定當前記錄的總數。
• NF :用於指定記錄中字段的總數。
• FS :它包含字段分隔符,用於分隔輸入行上的字段。
• RS :它存儲當前記錄分隔符。
• OFS:存儲輸出字段分隔符,用於在awk 打印時分隔字段。
• ORS:存儲輸出記錄分隔符,用於在awk 打印時分隔輸出行。

現在,使用以下語法從文件 contents.txt 打印字段 1 和 3:

awk '{print $1,$3}' contents.txt

您應該只看到文件 contents.txt 的第一個和第三個字段:

hitesh sales
jayesh account
vyom purchase
bhavesh sales
rajesh sales
niraj account
jay purchase
deep sales

您可以將 NR 與 AWK 命令一起使用以打印所有行以及行號:

awk '{print NR,$0}' contents.txt

輸出:

1 hitesh engineer sales 30000
2 jayesh director account 25000
3 vyom manager purchase 20000
4 bhavesh engineer sales 30000
5 rajesh directory sales 40000
6 niraj clerk account 20000
7 jay peon purchase 23000
8 deep clerk sales 20000

您可以使用 NF 顯示最後一個字段,使用 $1 顯示第一個字段:

awk '{print $1,$NF}' contents.txt

這將打印文件 contents.txt 的第一個和最後一個字段:

hitesh 30000
jayesh 25000
vyom 20000
bhavesh 30000
rajesh 40000
niraj 20000
jay 23000
deep 20000

要打印從 2 到 5 的行號,請使用 NR 變量,如下所示:

awk 'NR==2, NR==5 {print NR,$0}' contents.txt

輸出:

2 jayesh director account 25000
3 vyom manager purchase 20000
4 bhavesh engineer sales 30000
5 rajesh directory sales 40000

要使用 NR 計算文件 contents.txt 中的行數:

awk 'END { print NR } ' contents.txt

您應該看到以下輸出:

8

BEGIN 和 END 塊

還有可選的 BEGIN 和 END 塊,它們可以包含分別在文件處理之前和之後執行的命令。 BEGIN 塊用於在處理記錄之前執行操作,而 END 塊用於在處理記錄之後執行操作。

將 BEGIN 和 END 塊與 AWK 命令一起使用的基本語法如下所示:

awk 'BEGIN { action; } /search/ { action; } END { action; }' input_file

您可以使用 BEGIN 和 END 塊打印有關正在打印的字段的信息。
下列 example 將在處理文件 contents.txt 中每條記錄的第二個字段之前和之後打印消息:

awk 'BEGIN { print "Start Process." }; { print $2 }; END { print "End Process." }' contents.txt

輸出:

Start Process.
engineer
director
manager
engineer
directory
clerk
peon
clerk
End Process.

您還可以使用 BEGIN 和 END 塊來轉換文件中的數據並將其轉換為表格。 下列 example 將文件 /etc/passwd 轉換為表:

awk 'BEGIN { FS=":"; print "UserttUIDttGIDttHomettShelln--------------"; } {print $1,"tt",$3,"tt",$4,"tt",$6,"tt",$7;} END { print "---------nFile Complete" }' /etc/passwd

輸出:

User UID GID Home Shell
--------------
root 0 0 /root /bin/bash
daemon 1 1 /usr/sbin /usr/sbin/nologin
bin 2 2 /bin /usr/sbin/nologin
sys 3 3 /dev /usr/sbin/nologin
sync 4 65534 /bin /bin/sync
games 5 60 /usr/games /usr/sbin/nologin
man 6 12 /var/cache/man /usr/sbin/nologin
lp 7 7 /var/spool/lpd /usr/sbin/nologin
mail 8 8 /var/mail /usr/sbin/nologin
news 9 9 /var/spool/news /usr/sbin/nologin
uucp 10 10 /var/spool/uucp /usr/sbin/nologin
proxy 13 13 /bin /usr/sbin/nologin
www-data 33 33 /var/www /usr/sbin/nologin
---------
File Complete

條件搜索

AWK 命令還支持多種條件語句,包括 if、while 循環、for 循環等等。 這將幫助您獲取符合特定條件的行。

下列 example 將使用“if”條件打印在第三個字段中包含“sales”的所有行:

awk '{ if ($3 ~ /sales/) print}' contents.txt

輸出:

hitesh engineer sales 30000
bhavesh engineer sales 30000
rajesh directory sales 40000
deep clerk sales 20000

下列 example 將使用“for”循環打印每條記錄的前三個字段,每行一個。

awk '{ for (i = 1; i <= 3; i++) print $i }' contents.txt

輸出:

hitesh
engineer
sales
jayesh
director
account
vyom
manager
purchase
bhavesh
engineer
sales
rajesh
directory
sales
niraj
clerk
account
jay
peon
purchase
deep
clerk
sales

下列 example 將使用“while”循環打印每條記錄的前兩個字段,每行一個。

awk '{ i = 1; while ( i <= 2 ) { print $i i++ } }' contents.txt

輸出:

hitesh1
engineer2
jayesh1
director2
vyom1
manager2
bhavesh1
engineer2
rajesh1
directory2
niraj1
clerk2
jay1
peon2
deep1
clerk2

處理其他命令的輸出

您還可以使用 AWK 命令來解析其他命令的輸出,而不是指定文件名。 “ip a”命令打印系統IP、Mac地址等網絡相關信息,如下圖:

ip a s wlan0

輸出:

2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 4c:bb:58:9c:f5:55 brd ff:ff:ff:ff:ff:ff
inet 172.20.10.3/28 brd 172.20.10.15 scope global wlan0
valid_lft forever preferred_lft forever
inet6 2401:4900:1d71:ef26:8846:95b2:4ca8:aa7d/64 scope global temporary dynamic
valid_lft 600574sec preferred_lft 81574sec
inet6 2401:4900:1d71:ef26:4ebb:58ff:fe9c:f555/64 scope global dynamic
valid_lft forever preferred_lft forever
inet6 fe80::4ebb:58ff:fe9c:f555/64 scope link
valid_lft forever preferred_lft forever

現在,您可以使用 AWK 命令僅打印系統的 IP 地址,如下所示:

ip a s wlan0 | awk -F '[/ ]+' '/inet / {print $3}

您應該看到以下輸出:

172.20.10.3

AWK 命令高級示例

示例 1: AWK 命令允許您打印具有某些指定字符數的行。 為了 example, 打印超過 27 個字符的行,使用以下命令:

awk 'length($0) > 27' contents.txt

輸出:

jayesh director account 25000
bhavesh engineer sales 30000
rajesh directory sales 40000

示例 2: 檢查給定數字的立方體

要將給定數字的立方體打印到 5,請運行以下命令:

awk 'BEGIN { for(i=1; i<=5; i++) print "Cube of",i,"is",i*i*i; }'

輸出:

Cube of 1 is 1
Cube of 2 is 8
Cube of 3 is 27
Cube of 4 is 64
Cube of 5 is 125

示例 3: 計算指定文件中的行數

您可以檢查指定文件中的行數並使用以下命令打印它:

awk 'END { print NR }' contents.txt

輸出:

8

示例 4: 找到給定文件中最長的行並打印字符

您可以找到給定文件中最長的一行,並使用以下命令打印該行的字符:

awk '{ if (length($0) > max) max = length($0) } END { print max }' contents.txt

輸出

29

示例 5: 對給定文件的第一列進行排序

要對文件 contents.txt 的第一列進行排序和打印,請運行以下命令:

awk -F: '{ print $1 }' contents.txt | sort

輸出:

bhavesh engineer sales 30000
deep clerk sales 20000
hitesh engineer sales 30000
jayesh director account 25000
jay peon purchase 23000
niraj clerk account 20000
rajesh directory sales 40000
vyom manager purchase 20000

示例 6: 打印偶數行

要在文件 contents.txt 中僅打印偶數行,請運行以下命令:

awk 'NR % 2 == 0' contents.txt

輸出:

jayesh director account 25000
bhavesh engineer sales 30000
niraj clerk account 20000
deep clerk sales 20000

示例 7: 更改字段分隔符

您可以將文件分隔符從空格更改為 | 並使用以下命令打印它:

awk 'BEGIN{OFS="|"}{print $1,$2,$3,$4}' contents.txt

輸出:

hitesh|engineer|sales|30000
jayesh|director|account|25000
vyom|manager|purchase|20000
bhavesh|engineer|sales|30000
rajesh|directory|sales|40000
niraj|clerk|account|20000
jay|peon|purchase|23000
deep|clerk|sales|20000

結論

在本教程中,您學習瞭如何使用 AWK 命令匹配指定的模式,然後執行關聯的操作。 我希望您對如何使用 AWK 命令來操作、格式化和有選擇地打印文本文件有一個清晰的認識。