Linux三劍客傳 | 老大:AWK
來源:編程三分鐘
ID:coding3min
作者:小熊愛編程
概述
awk
同sed
命令類似,只不過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
(鬼知道我為什麼會記得這麼多亂七八糟的命令。)