久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Linux awk 命令詳解

 hucy_Bioinfo 2021-08-19

awk是行處理器:相比較屏幕處理的優(yōu)點(diǎn),,在處理龐大文件時(shí)不會(huì)出現(xiàn)內(nèi)存溢出或處理緩慢的問題,常用來格式化文本信息,。

awk處理過程:依次對(duì)每一行進(jìn)行處理,,然后輸出。①讀取被匹配到的行數(shù)據(jù),;②按照輸入分隔符將整行數(shù)據(jù)分成n段,;③將每一段保存到awk的內(nèi)置變量,依次為$1~$n,;④格式化輸出,;全部輸出使用$0

1. awk 命令形式

awk [-F|-f|-v] 'BEGIN{} //{command1; command2} END{}' file

[-F|-f|-v]: -F指定分隔符,,-f調(diào)用腳本,,-v定義變量 var=value
' ':引用代碼塊
BEGIN:初始化代碼塊,在對(duì)每一行進(jìn)行處理之前,,初始化代碼,,主要是引用全局變量,設(shè)置FS分隔符
//:匹配代碼塊,,可以是字符串或正則表達(dá)式
{}:命令代碼塊,,包含一條或多條命令
:多條命令使用分號(hào)分隔
END:結(jié)尾代碼塊,,在對(duì)每一行進(jìn)行處理之后再執(zhí)行的代碼塊,,主要是進(jìn)行最終計(jì)算或輸出結(jié)尾摘要信息

2. 特殊要點(diǎn)

$0:表示整個(gè)當(dāng)前行
$1:每行第一個(gè)字段
NF:字段數(shù)量變量
NR:每行的記錄號(hào),多文件記錄遞增
FNR:與NR類似,,不過多文件記錄不遞增,,每個(gè)文件都從1開始
\t:制表符
\n:換行符
FS:BEGIN時(shí)定義分隔符
RS:輸入的記錄分隔符, 默認(rèn)為換行符(即文本是按一行一行輸入)
~:匹配,,與==相比不是精確比較
!~:不匹配,,不精確比較
==:等于,必須全部相等,,精確比較
!=:不等于,,精確比較
&&:邏輯與
||:邏輯或
+:匹配時(shí)表示1個(gè)或1個(gè)以上
/[0-9][0-9]+/:兩個(gè)或兩個(gè)以上數(shù)字
/[0-9][0-9]*/:一個(gè)或一個(gè)以上數(shù)字
FILENAME:文件名
OFS:輸出字段分隔符, 默認(rèn)也是空格,,可以改為制表符等
ORS:輸出的記錄分隔符,,默認(rèn)為換行符,即處理結(jié)果也是一行一行輸出到屏幕
-F'[:#/]':定義三個(gè)分隔符

3. print 和 $0

print 是awk打印指定內(nèi)容的主要命令:

awk '{print}' /etc/passwd # awk '{print $0}' /etc/passwd
awk '{print " "}' /etc/passwd # 不輸出passwd的內(nèi)容,,而是輸出相同個(gè)數(shù)的空行,進(jìn)一步解釋了awk是一行一行處理文本
awk -F":" '{print $1}' /etc/passwd
awk -F: '{print $1; print $2}' /etc/passwd # 將每一行的前二個(gè)字段,,分行輸出
awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd # 輸出字段1,3,6,輸入分隔符為“:”,;輸出分隔符:"\t"

4. -F 指定分隔符

$1 為指定分隔符后,,第一個(gè)字段,$3第三個(gè)字段,, \t是制表符
一個(gè)或多個(gè)連續(xù)的空格或制表符看做一個(gè)定界符,,即多個(gè)空格看做一個(gè)空格。

awk -F":" '{print $1}' /etc/passwd
awk -F":" '{print $1 $3}' /etc/passwd # $1與$3相連輸出,,不分隔
awk -F":" '{print $1,$3}' /etc/passwd # 多了一個(gè)逗號(hào),,$1與$3使用空格分隔
awk -F":" '{print $1 " " $3}' /etc/passwd # $1與$3之間手動(dòng)添加空格分隔
awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd # 自定義輸出
awk -F: '{print NF}' /etc/passwd # 顯示每行有多少字段
awk -F: '{print $NF}' /etc/passwd # 將每行第NF個(gè)字段的值打印出來
awk -F: 'NF==4 {print }' /etc/passwd # 顯示只有4個(gè)字段的行
awk -F: 'NF>2{print $0}' /etc/passwd # 顯示每行字段數(shù)量大于2的行
awk '{print NR,$0}' /etc/passwd # 輸出每行的行號(hào)
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd # 依次打印行號(hào),字段數(shù),,最后字段值,,制表符,每行內(nèi)容
awk -F: 'NR==5{print}' /etc/passwd # 顯示第5行
awk -F: 'NR==5 || NR==6{print}' /etc/passwd # 顯示第5行和第6行
route -n|awk 'NR!=1{print}' # 不顯示第一行

5. 輸出分隔符OFS

awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
# 輸出字段6匹配WAIT的行,,其中輸出每行行號(hào),,字段4,5,6,并使用制表符分割字段

6. -f 指定腳本文件

awk -f script.awk filename BEGIN{FS=":"} {print $1} # 效果與awk -F":" '{print $1}'相同,只是分隔符使用FS在代碼自身中指定

awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' filename
# I find 4 blank lines.

ls -l | awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' #計(jì)算文件大小
# total size is 17487

7. // 匹配代碼塊

//純字符匹配,;!//純字符不匹配,;
~//字段值匹配;!~//字段值不匹配,;
~/a1|a2/字段值匹配a1a2 ,。

awk '/mysql/' /etc/passwd # grep "mysql" /etc/passwd
awk '/mysql/{print }' /etc/passwd
awk '/mysql/{print $0}' /etc/passwd # 三條指令結(jié)果一樣

awk '!/mysql/{print $0}' /etc/passwd # grep -v "mysql" /etc/passwd # 輸出不匹配mysql的行
awk '/mysql|mail/{print}' /etc/passwd # grep -w "mail\|mysql" /etc/passwd #grep -e "mysql" -e "mail" /etc/passwd
awk '!/mysql|mail/{print}' /etc/passwd # grep -v "mail\|mysql" /etc/passwd

awk -F: '/mail/,/mysql/{print}' /etc/passwd # 區(qū)間匹配
awk '/[2][7][7]*/{print $0}' /etc/passwd # 匹配包含27為數(shù)字開頭的行,如27,,277,,2777...
awk -F: '$1~/mail/{print $1}' /etc/passwd # $1匹配指定內(nèi)容才顯示
awk -F: '{if($1~/mail/) print $1}' /etc/passwd # 與上面相同
awk -F: '$1!~/mail/{print $1}' /etc/passwd # 不匹配
awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd

8. 條件表達(dá)式

== != > >=

awk -F":" '$1=="mysql"{print $3}' /etc/passwd
awk -F":" '{if($1=="mysql") print $3}' /etc/passwd # 與上面相同
awk -F":" '$1!="mysql"{print $3}' /etc/passwd # 不等于
awk -F":" '$3>1000{print $3}' /etc/passwd # 大于
awk -F":" '$3>=100{print $3}' /etc/passwd # 大于等于
awk -F":" '$3<1{print $3}' /etc/passwd # 小于
awk -F":" '$3<=1{print $3}' /etc/passwd # 小于等于

9. 邏輯運(yùn)算符

&& ||

awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd # 邏輯與,$1匹配mail,,并且$3>8
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd # 邏輯或
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd

10. 數(shù)值運(yùn)算

awk -F: '$3 > 100' /etc/passwd
awk -F: '$3 > 100 || $3 < 5' /etc/passwd
awk -F: '$3+$4 > 200' /etc/passwd
awk -F: '/mysql|mail/{print $3+10}' /etc/passwd # 第三個(gè)字段加10打印
awk -F: '/mysql/{print $3-$4}' /etc/passwd # 減法
awk -F: '/mysql/{print $3*$4}' /etc/passwd # 求乘積
awk '/MemFree/{print $2/1024}' /proc/meminfo # 除法
awk '/MemFree/{print int($2/1024)}' /proc/meminfo # 取整

ls -l | awk '{print int($5/1024/1024/1024)}' | paste -s -d + |bc

11. if 語(yǔ)句

必須用在{}中,,且比較內(nèi)容用()擴(kuò)起來。

awk -F: '{if($1~/mail/) print $1}' /etc/passwd # 簡(jiǎn)寫
awk -F: '{if($1~/mail/) {print $1}}' /etc/passwd # 全寫
awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd # if...else...

awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A++; print "large"} else {B++; print "small"}} END{print A,"\t",B}' /etc/passwd # ID大于100,A加1,,否則B加1
awk -F: '{if($3<100) next; else print}' /etc/passwd # 小于100跳過,,否則顯示
awk -F: 'BEGIN{i=1} {if(i<NF) print NR,NF,i++ }' /etc/passwd
awk -F: 'BEGIN{i=1} {if(i<NF) {print NR,NF} i++ }' /etc/passwd
# 另一種形式
awk -F: '{print ($3>100 ? "yes":"no")}' /etc/passwd
awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}' /etc/passwd

12. while語(yǔ)句

awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd

13. 格式化輸出

語(yǔ)法:

printf FORMAT, item1,item2,,……

格式符:
%s:顯示字符串
%c:顯示字符對(duì)應(yīng)的ASCII碼
%d,%i:顯示十進(jìn)制整數(shù)
%e,,%E:顯示科學(xué)計(jì)數(shù)法數(shù)值
%f:顯示浮點(diǎn)數(shù)
%g,%G:以科學(xué)計(jì)數(shù)法或者浮點(diǎn)形式顯示數(shù)值
%u:顯示無符號(hào)整數(shù)
%%:顯示%

# 打印每行前三個(gè)字段,,指定第一個(gè)字段輸出字符串類型(長(zhǎng)度為8),,第二個(gè)字段輸出字符串類型(長(zhǎng)度為8),,第三個(gè)字段輸出字符串類型(長(zhǎng)度為10)
# printf 表示格式輸出
# % 格式化輸出分隔符
# -8 長(zhǎng)度為8個(gè)字符
# s 表示字符串類型
netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'
netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s \n",NR,$1,$2,$3}'

14. 輸出處理結(jié)果到文件

route -n|awk 'NR!=1{print > "./fs"}' # ①在命令代碼塊中直接輸出
route -n|awk 'NR!=1{print}' > ./fs # ②使用重定向進(jìn)行輸出

15. 數(shù)組

在 awk 中數(shù)組叫做關(guān)聯(lián)數(shù)組(associative arrays),由于下標(biāo)既能夠是數(shù)也能夠是串,。awk 中的數(shù)組不必提前聲明,,也不必聲明大小。數(shù)組元素用 0 或空串來初始化,,這依據(jù)上下文而定,。

(1)定義方法

# 1 用數(shù)值作數(shù)組索引(下標(biāo)) ;2 用字符串作數(shù)組索引(下標(biāo)) ,。
Tarray[1]="cheng mo"
Tarray[2]="800927"
Tarray["first"]="cheng"
Tarray["last"]="mo"
Tarray["birth"]="800927"

使用中 print Tarray[1] 將得到"cheng mo",;而 print Tarray[2] 和 print[“birth”] 都將得到"800927" 。

(2) 數(shù)組相關(guān)函數(shù)

awk --version
awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),lens;}' # length返回字符串以及數(shù)組長(zhǎng)度,,split進(jìn)行切割字符串為數(shù)組,,也會(huì)返回切割得到數(shù)組長(zhǎng)度。
awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}' # asort對(duì)數(shù)組進(jìn)行排序,,返回?cái)?shù)組長(zhǎng)度,。
awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}' # for…in 輸出,由于數(shù)組是關(guān)聯(lián)數(shù)組,,默認(rèn)是無序的,。
awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}' # 有序數(shù)組,須要通過下標(biāo)獲得

注意:數(shù)組下標(biāo)是從1開始,。

awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if(tB["c"]!="1"){print "no found";};for(k in tB){print k,tB[k];}}' #僅僅要通過數(shù)組引用它的key,,就會(huì)自己主動(dòng)創(chuàng)建該序列.
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";};for(k in tB){print k,tB[k];}}' #if(key in array) 通過這個(gè)方法推斷數(shù)組中是否包括”key”鍵值。
awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}' # delete array[key]能夠刪除,,相應(yīng)數(shù)組key的,,序列值

(3) 二維數(shù)組使用(多維數(shù)組使用)

awk的多維數(shù)組在本質(zhì)上是一維數(shù)組,更確切一點(diǎn),,awk在存儲(chǔ)上并不支持多維數(shù)組,。awk提供了邏輯上模擬二維數(shù)組的訪問方式。例 如,,array[2,4] = 1這種訪問是同意的,。
awk使用一個(gè)特殊的字符串SUBSEP (\034)作為切割字段,在上面的樣例中,,關(guān)聯(lián)數(shù)組array存儲(chǔ)的鍵值實(shí)際上是2\0344,。
相似一維數(shù)組的成員測(cè)試,多維數(shù)組能夠使用 
if ( (i,j) in array)這種語(yǔ)法,,可是下標(biāo)必須放置在圓括號(hào)里,。相似一維數(shù)組的循環(huán)訪問,多維數(shù)組使用for ( item in array )這種語(yǔ)法遍歷數(shù)組,。
與一維數(shù)組不同的是,,多維數(shù)組必須使用
split()函數(shù)來訪問單獨(dú)的下標(biāo)分量,。split ( item, subscr, SUBSEP)

awk 'BEGIN{ for(i=1;i<=9;i++) { for(j=1;j<=9;j++) { tarr[i,j]=i*j; print i,"*",j,"=",tarr[i,j]; } } }'
awk 'BEGIN{ for(i=1;i<=9;i++) { for(j=1;j<=9;j++) { tarr[i,j]=i*j; } } for(m in tarr) { split(m,tarr2,SUBSEP); print tarr2[1],"*",tarr2[2],"=",tarr[m]; } }'

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'
netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'

16. 應(yīng)用

awk -F: '{print NF}' helloworld.sh #輸出文件每行有多少字段
awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh # 輸出前5個(gè)字段
awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh # 輸出前5個(gè)字段并使用制表符分隔輸出
awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh # 制表符分隔輸出前5個(gè)字段,并打印行號(hào)

awk -F'[:#]' '{print NF}' helloworld.sh # 指定多個(gè)分隔符: #,,輸出每行多少字段
awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh # 制表符分隔輸出多字段

# 計(jì)算/home目錄下,,普通文件的大小,使用KB作為單位
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",sum/1024,"KB"}'
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is:",int(sum/1024),"KB"}' # int是取整的意思

# 統(tǒng)計(jì)netstat -anp 狀態(tài)為L(zhǎng)ISTEN和CONNECT的連接數(shù)量分別是多少
netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'

# 統(tǒng)計(jì)/home目錄下不同用戶的普通文件的總數(shù)是多少,?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'

17. 總結(jié)

(1) 輸出命令:print

要點(diǎn)1:各字段之間用逗號(hào)分隔'{print $1,$2}',,若不用逗號(hào)'{print $1$2}' 則awk會(huì)默認(rèn)連接兩個(gè)字段的內(nèi)容。
要點(diǎn)2:print輸出的字段可以是數(shù)值,,
$n,變量,,或awk表達(dá)式,。要想引用$n的值,不能把其放入""內(nèi),。
要點(diǎn)3:若省略字段,,則默認(rèn)輸出
$0

(2) 變量:分為內(nèi)置變量和自定義變量

內(nèi)置變量:

  • FS:input field seperator,。輸入字段分隔符,。沒有指定輸入分隔符(FS),默認(rèn)以空格來分隔,??梢允褂?v來指定分隔符,如-v FS=":",,也可以直接使用-F直接指名,,如 -F ","

  • OFS:outpu field seperator,。輸出字段分隔符,。可以使用-v來指定分隔符,,如 -v OFS="," ,。

  • RS:input record seperator 。輸入時(shí)的換行符

  • ORS:output record seperator,。輸出時(shí)的換行符

  • NF:number of field,。每一行的字段數(shù)量。$NF代表的是輸出文件的每一行的最后一個(gè)字段,。

  • NR:numbe of record ,。顯示文件的行數(shù)。每處理一行就會(huì)輸出一次行數(shù),。

自定義變量:

-v variable=value或在program中直接定義,。

(3) 格式化輸出 printf

要點(diǎn)一:FORMAT必須給出,;
要點(diǎn)二:printf輸出是不會(huì)自動(dòng)換行,若需要換行可以使用換行控制符 \n,;
要點(diǎn)三:FORMAT中給出的格式符需要與各字段一一對(duì)應(yīng),;
要點(diǎn)四:在printf中可以加入提示性字符串;
#[.#]:第一個(gè)#用來控制字符寬度,,第二個(gè)用來控制小數(shù)位數(shù),。
-:左對(duì)齊。注意默認(rèn)為右對(duì)齊,。
+:顯示數(shù)值的符號(hào),。

(4) 操作符:

算數(shù)運(yùn)算:+ - * / % ^ -x +x
比較運(yùn)算:> >= = < <= != ==
賦值運(yùn)算:++,–,,+=,,-=,*=,,%=
字符串操作:默認(rèn)為字符串拼接
邏輯操作符:&&與,、|| 或、,!非

(5) 模式匹配:

~:是否匹配:左側(cè)字符是否被右側(cè)模式匹配,;
!~:是否不匹配,,:左側(cè)字符是否不被右側(cè)模式匹配,;
/pattern1/,/pattern2/:處理 pattern1 到 pattern2 之間(不包含pattern2)。從pattern1匹配的行開始,,到pattern2匹配的行結(jié)束,。

(6) BEGIN和END模式

是給程序賦予初始狀態(tài)和在程序結(jié)束之后執(zhí)行一些掃尾的工作。
BEGIN{}:任何在BEGIN之后列出的操作(在{}內(nèi))將在awk開始掃描輸入之前執(zhí)行一次,。
END{}:END之后列出的操作將在掃描完全部的輸入之后執(zhí)行一次,。

參考閱讀:
https://www.cnblogs.com/wxxjianchi/p/9143936.html
https://www.jianshu.com/p/ea22c809ae9f

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多