日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shell学习(4)- awk

發(fā)布時(shí)間:2025/7/25 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shell学习(4)- awk 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

awk是一個(gè)強(qiáng)大的文本分析工具,相對(duì)于grep的查找,sed的編輯,awk在其對(duì)數(shù)據(jù)分析并生成報(bào)告時(shí),顯得尤為強(qiáng)大。簡(jiǎn)單來說awk就是把文件逐行的讀入,以空格為默認(rèn)分隔符將每行切片,切開的部分再進(jìn)行各種分析處理。

awk有3個(gè)不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk其名稱得自于它的創(chuàng)始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個(gè)字母。實(shí)際上 AWK 的確擁有自己的語言: AWK 程序設(shè)計(jì)語言 , 三位創(chuàng)建者已將它正式定義為“樣式掃描和處理語言”。它允許您創(chuàng)建簡(jiǎn)短的程序,這些程序讀取輸入文件、為數(shù)據(jù)排序、處理數(shù)據(jù)、對(duì)輸入執(zhí)行計(jì)算以及生成報(bào) 表,還有無數(shù)其他的功能

使用方法

awk'{pattern + action}' {filenames}

awk :對(duì)于文件中一行行的獨(dú)處來執(zhí)行操作?

?

調(diào)用方法

1.命令行方式

awk [-F ?field-separator] ?'commands' ?input-file(s)

其中,commands 是真正awk命令,[-F域分隔符]是可選的。 input-file(s) 是待處理的文件。

awk中,文件的每一行中,由域分隔符分開的每一項(xiàng)稱為一個(gè)域。通常,在不指名-F域分隔符的情況下,默認(rèn)的域分隔符是空格。

2.shell腳本方式

將所有的awk命令插入一個(gè)文件,并使awk程序可執(zhí)行,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調(diào)用。

相當(dāng)于shell腳本首行的:#!/bin/sh

可以換成:#!/bin/awk

3.將所有的awk命令插入一個(gè)單獨(dú)文件,然后調(diào)用:

awk -f awk-script-file input-file(s)

其中,-f選項(xiàng)加載awk-script-file中的awk腳本,input-file(s)跟上面的是一樣的。

?

工作流程

awk的工作流程師這樣的,讀入有'\n'換行符分割的一條記錄,然后將記錄按指定的域分隔符劃分域,填充域, $0則表示所有域,$1表示第一個(gè)域,$n表示第n個(gè)域。 默認(rèn)域分隔符是"空白鍵" 或 "[tab]鍵",所以$1表示登錄用戶,$3表示登錄用戶ip,以此類推

1.基本用法

只顯示最近登錄的5個(gè)賬號(hào)

[root@www ~]$ last -n 5 | awk'{print $1}' root root root dmtsai root

只顯示/etc/passwd的賬戶

[root@www ~]$ cat /etc/passwd |awk -F ':''{print $1}' root daemon bin sys

如果只是顯示/etc/passwd的賬戶和賬戶對(duì)應(yīng)的shell,而賬戶與shell之間以tab鍵分割

[root@www ~]$ cat /etc/passwd |awk -F ':''{print $1"\t"$7}' root /bin/bash daemon /bin/sh bin /bin/sh sys /bin/sh

搜索/etc/passwd有root關(guān)鍵字的所有行

[root@www ~]$ cat /etc/passwd | awk -F':' '/root/' root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin

找/etc/passwd 以root開頭的

[yangjiao@www ~]$ cat /etc/passwd | awk -F':' '/^root/' root:x:0:0:root:/root:/bin/bash

2.內(nèi)置變量

ARGC??

命令行參數(shù)個(gè)數(shù)

NF????

?瀏覽記錄的域個(gè)數(shù)

AGRV??

命令行參數(shù)排列

NR??

已讀的記錄數(shù)???

ENVIRON??

支持隊(duì)列中系統(tǒng)環(huán)境變量的使用

OFS??

輸出域分隔符

FILENAME??

awk瀏覽的文件名??

ORS?

輸出記錄分隔符

FNR??

瀏覽文件的記錄數(shù)??

RS??

控制記錄分隔符

FS??

設(shè)置輸入域分隔符,同- F選項(xiàng)

NF????

?瀏覽記錄的域個(gè)數(shù)

打印每一行的行數(shù)

[root@www ~]$ ls -l | awk '{print NR " " $1}' 1 total 2 drwx------ 3 drwx------+ 4 drwx------+ 5 drwx------+ 6 drwx------@ 7 drwx------+ 8 drwx------+ 9 drwx------+ 10 drwxr-xr-x+

再理解如下應(yīng)該比較簡(jiǎn)單了

[root@www ~]$awk -F ':' '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/usr/sbin/nologin filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/usr/sbin/nologin filename:/etc/passwd,linenumber:5,columns:7,linecontent:sync:x:4:65534:sync:/bin:/bin/sync filename:/etc/passwd,linenumber:6,columns:7,linecontent:games:x:5:60:games:/usr/games:/usr/sbin/nologin

3.數(shù)組和計(jì)算

因?yàn)?span id="ozvdkddzhkzd" class="s1">awk中數(shù)組的下標(biāo)可以是數(shù)字和字母,數(shù)組的下標(biāo)通常被稱為關(guān)鍵字(key)。值和關(guān)鍵字都存儲(chǔ)在內(nèi)部的一張針對(duì)key/value應(yīng)用hash的表格里。由于hash不是順序存儲(chǔ),因此在顯示數(shù)組內(nèi)容時(shí)會(huì)發(fā)現(xiàn),它們并不是按照你預(yù)料的順序顯示出來的。數(shù)組和變量一樣,都是在使用時(shí)自動(dòng)創(chuàng)建的,awk也同樣會(huì)自動(dòng)判斷其存儲(chǔ)的是數(shù)字還是字符串。一般而言,awk中的數(shù)組用來從記錄中收集信息,可以用于計(jì)算總和、統(tǒng)計(jì)單詞以及跟蹤模板被匹配的次數(shù)等等。

?

[root@www ~]$ awk -F ':''BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon 2 bin 3 sys 4 sync5 games

準(zhǔn)備測(cè)試文件

[root@www ~]$ cat test.txt 5555 4444 2222 3333 7777 8888
[root@www ~]awk '{name[x++]=$1};END{for(i=0;i<NR;i++) print i, name[i]}' test.txt
0 5555
1 4444
2 2222
3 3333
4 7777
5 8888

求和

[root@www ~]$awk '{sum+=$1} END {print "sum=",sum}' test.txt sum= 32219

求平均值

[root@www ~]$ awk '{sum+=$1} END {print "avg=",sum/NR}' test.txt avg= 5369.83

求最大值

[root@www ~]$ awk 'BEGIN {max=0} {if($1>max) max=$1 fi} END {print "MAX=",max}' test.txt MAX= 8888[root@www ~]$ awk 'BEGIN{max=0;print "max="max} {max=($1>max)?$1:max; print $1, "Now max is" max}' test.txt max=0 5555 Now max is5555 4444 Now max is5555 2222 Now max is5555 3333 Now max is5555 7777 Now max is7777 8888 Now max is8888

?

求最小值

[root@www ~]$ awk 'BEGIN{min=9999999}{if($1<min) min=$1} END {print "MIN=",min}' test.txt MIN= 2222

統(tǒng)計(jì)某個(gè)文件夾下的文件占用的字節(jié)數(shù)

[root@www ~]$ls -l | awk 'BEGIN{size=0;} {size=size+$5} END {print "size is", size}' size is 7729814

4.條件操作符

? ? <、<=、==、!=、>=、~匹配正則表達(dá)式、!~不匹配正則表達(dá)式

????匹配:awk '{if ($4~/ASIMA/) print $0}' temp?表示如果第四個(gè)域包含ASIMA,就打印整條

????精確匹配:awk '$3=="48" {print $0}' temp????只打印第3域等于"48"的記錄

????不匹配:? awk '$0 !~ /ASIMA/' temp??????打印整條不包含ASIMA的記錄

????不等于:? awk '$1 != "asima"' temp

????小于:??? awk '{if ($1<$2) print $1 "is smaller"}' temp

????設(shè)置大小寫: awk '/[Gg]reen/' temp??????打印整條包含Green,或者green的記錄

????任意字符: awk '$1 ~/^...a/' temp????打印第1域中第四個(gè)字符是a的記錄,符號(hào)’^’代表行首,符合’.’代表任意字符

????或關(guān)系匹配: awk '$0~/(abc)|(efg)/' temp???使用|時(shí),語句需要括起來

????AND與關(guān)系:? awk '{if ( $1=="a" && $2=="b" ) print $0}' temp

????OR或關(guān)系:?? awk '{if ($1=="a" || $1=="b") print $0}' temp

awk有三種循環(huán): while循環(huán);for循環(huán);special for循環(huán)。$ awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test。變量的初始值為1,若i小于可等于NF(記錄中域的個(gè)數(shù)),則執(zhí)行打印語句,且i增加1。直到i的值大于NF.$ awk '{for (i = 1; i<NF; i++) print NF,$i}' test。作用同上。bread continue 語句。break用于在滿足條件的情況下跳出循環(huán);continue用于在滿足條件的情況下忽略后面的語句,直接返回循環(huán)的頂端。如:{for ( x=3; x<=NF; x++) if ($x<0){print "Bottomed out!"; break}} {for ( x=3; x<=NF; x++)if ($x==0){print "Get next item"; continue}}next 語句從輸入文件中讀取一行,然后從頭開始執(zhí)行awk腳本。如:{if ($1 ~/test/){next}else {print} }exit 語句用于結(jié)束awk程序,但不會(huì)略過END塊。退出狀態(tài)為0代表成功,非零值表示出錯(cuò)。

? ??

if 語句 格式:{if (expression){statement; statement; ...}} $ awk '{if ($1 <$2) print $2 "too high"}' test。如果第一個(gè)域小于第二個(gè)域則打印。$ awk '{if ($1 < $2) {count++; print "ok"}}' test.如果第一個(gè)域小于第二個(gè)域,則count加一,并打印ok。

if/else語句,用于雙重判斷

格式:{if (expression){statement; statement; ...}else{statement; statement; ...}}

? ?$ awk '{if ($1 > 100) print $1 "bad" ; else print "ok"}' test。如果$1大于100則打印$1 bad,否則打印ok。

? ? $ awk '{if ($1 > 100){ count++; print $1} else {count--; print $2}' test。如果$1大于100,則count加一,并打印$1,否則count減一,并打印$1。

[root@www ~]$awk 'BEGIN {BASE="7000"} {if($1<BASE) print $0}' test.txt 5555 4444 2222 3333 [root@www ~]$ awk '{total+=$1};END{print total}' test.txt 32219

5.BEGIN和END模塊

BEGIN模塊后緊跟著動(dòng)作塊,這個(gè)動(dòng)作塊在awk處理任何輸入文件之前執(zhí)行。所以它可以在沒有任何輸入的情況下進(jìn)行測(cè)試。它通常用來改變內(nèi)建變量的值,如OFS,RS和FS等,以及打印標(biāo)題

END不匹配任何的輸入文件,但是執(zhí)行動(dòng)作塊中的所有動(dòng)作,它在整個(gè)輸入文件處理完成后被執(zhí)行。如$ awk 'END{print "The number of records is" NR}' test,上式將打印所有被處理的記錄數(shù)。

?

6.舉個(gè)例子

有a.txt如下

"北京" =>1 "上海" =>2 "天津"=>3 "重慶"=>4 "河北省"=>5 "山西省"=>6 "內(nèi)蒙古"=>7 "遼寧省"=>8 "吉林省"=>9 "黑龍江省"=>10

 現(xiàn)把key和value互換并去掉空格,用如下命令,或者先去掉空格,用下邊第二條命令

cat a.txt | awk -F'=>' '{printf("%s=>%s\n",$2,$1)}' | sed 's/\s\+//g' > b.txt

? cat a.txt | sed 's/\s\+//g' | awk -F'=>' '{printf("%s => %s\n",$2,$1)}' > b.txt

 修改完后的b.txt如下

1=>"北京" 2=>"上海" 3=>"天津" 4=>"重慶" 5=>"河北省" 6=>"山西省" 7=>"內(nèi)蒙古" 8=>"遼寧省" 9=>"吉林省" 10=>"黑龍江省"

  

?

參考文檔:https://www.cnblogs.com/losbyday/p/5854707.html

? ? ? ? ? ? ? ?https://www.cnblogs.com/losbyday/p/5854725.html

? ? ? ? ? ? ??https://www.cnblogs.com/bugingcode/p/8287914.html

? ? ? ? ? ? ? https://www.cnblogs.com/emanlee/p/3327576.html

轉(zhuǎn)載于:https://www.cnblogs.com/kumufengchun/p/10156469.html

總結(jié)

以上是生活随笔為你收集整理的shell学习(4)- awk的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。