來源:編程三分鐘

ID:coding3min

作者:小熊愛編程

概述

awksed命令類似,只不過sed擅長取行,awk命令擅長取列。(根據瞭解awk是一種語言,不過我們只關注他處理文本的功能,用的好的話幾乎可以取代excel)

原理:一般是遍歷一個文件中的每一行,然後分別對文件的每一行進行處理用法:

awk [可選的命令行選項] BEGIN{命令 } pattern{ 命令 } END{ 命令 } 文件名

列印某幾列

$ echo I love you | awk {print $3 $2 $1}
youloveI

我們將字元串 I love you 通過管道傳遞給awk命令,相當於awk處理一個文件,該文件的內容就是I love you,默認通過空格作為分隔符(不管列之間有多少個空格都將當作一個空格處理)I love you就分割成三列了。

假如分割符號為.,可以這樣用

$ echo 192.168.1.1 | awk -F "." {print $2}
168

條件過濾

我們知道awk的用法是這樣的,那麼pattern部分怎麼用呢?

awk [可選的命令行選項] BEGIN{命令 } pattern{ 命令 } END{ 命令 } 文件名

$ cat score.txt
tom 60 60 60
kitty 90 95 87
jack 72 84 99
$ awk $2>=90{print $0} score.txt
kitty 90 95 87

$2>=90 表示如果當前行的第2列的值大於90則處理當前行,否則不處理。說白了pattern部分是用來從文件中篩選出需要處理的行進行處理的,這部分是空的代表全部處理。pattern部分可以是任何條件表達式的判斷結果,例如>,<,==,>=,<=,!=同時還可以使用+,-,*,/運算與條件表達式相結合的複合表達式,邏輯 &&,||,!同樣也可以使用進來。另外pattern部分還可以使用 /正則/ 選擇需要處理的行。

判斷語句

判斷語句是寫在pattern{ 命令 }命令中的,他具備條件過濾一樣的作用,同時他也可以讓輸出更豐富

$ awk {if($2>=90 )print $0} score.txt
kitty 90 95 87
$ awk {if($2>=90 )print $1,"優秀"; else print $1,"良好"} score.txt
tom 良好
kitty 優秀
jack 良好

BEGIN 定義表頭

awk [可選的命令行選項] BEGIN{命令 } pattern{ 命令 } END{ 命令 } 文件名

使用方法如下:

$ awk BEGIN{print "姓名 語文 數學 英語"}{printf "%-8s%-5d%-5d%-5d
",$1,$2,$3,$4} score.txt
姓名 語文數學英語
tom 60 60 60
kitty 90 95 87
jack 72 84 99

這裡要注意,我為了輸出格式好看,做了左對齊的操作(%-8s左對齊,寬8位),printf用法和c++類似。

不僅可以用來定義表頭,還可以做一些變數初始化的工作,例如

$ awk BEGIN{OFMT="%.2f";print 1.2567,12E-2}
1.26 0.12

這裡OFMT是個內置變數,初始化數字輸出格式,保留小數點後兩位。

END 添加結尾符

和BEGIN用法類似

$ echo ok | awk {print $1}END{print "end"}
ok
end

數據計算

這個地方我要放大招了!上面的知識點你都記住了嗎?

$ awk BEGIN{print "姓名 語文 數學 英語 總成績";
sum1=0;sum2=0;sum3=0;sumall=0}
{printf "%5s%5d%5d%5d%5d
",$1,$2,$3,$4,$2+$3+$4;
sum1+=$2;sum2+=$3;sum3+=$4;sumall+=$2+$3+$4}
END{printf "%5s%5d%5d%5d%5d
","總成績",sum1,sum2,sum3,sumall}
score.txt
姓名 語文 數學 英語 總成績
tom 60 60 60 180
kitty 90 95 87 272
jack 72 84 99 255
總成績 222 239 246 707

因為命令太長,末尾我用符號換行了。。

  • BEGIN體裏我輸出了表頭,並給四個變數初始化0
  • pattern體裏我輸出了每一行,並累加運算
  • END體裏我輸出了總統計結果當然了,一個正常人在用linux命令的時候是不會輸入那麼多格式化符號來對齊的,所以新命令又來了column -t(鬼知道我為什麼會記得這麼多亂七八糟的命令。)

有用的內置變數

NF:表示當前行有多少個欄位,因此$NF就代表最後一個欄位

NR:表示當前處理的是第幾行FILENAME:當前文件名OFMT:數字輸出的格式,默認為%.6g。表示只列印小數點後6 位

$ awk -F : {print NR ") " $1} demo.txt
1) root
2) daemon
3) bin
4) sys
5) sync

內置函數

awk定義了很多內置函數,用awk來寫shell腳本倒是一個不錯的選擇,但是大多數我們是用不上的,以下是常用函數

$ echo 1 2 | awk {print $1+sqrt($2)}

2.41421

隨機數,先設置種子再隨機

rand() 0 <= n < 1,srand([expr]) |將 rand 函數的種子值設置為 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。

$ echo 1 | awk BEGIN{srand()}{print rand()}

0.929885

字元串

系統常用

不常用算數:

另外我們整理了一個學習知識庫,你可以看一下:

【超全整理】《Linux雲計算從入門到精通》系列實戰筆記全放送 | Linux運維部落?

magedu.com

希望大家有所幫助,祝願大家學有所成。獲取更多技術知識點+v156 5219 9186,歡豆在線解答哦~


推薦閱讀:
相關文章