1. 程式人生 > >grep、sed、awk基礎

grep、sed、awk基礎

sed grep awk

grep

grep :根據模式,搜索文本,並將符合模式的文本行顯示出來,

使用基本正則表達式定義的模式來過濾文本的命令:

-i :忽略大小寫

--color :加上顏色,

-v :顯示沒有被模式匹配到的行

-n:顯示匹配到的行在文件中的行數

-w:精確匹配,只匹配整個單詞,而不是字符串的一部分

-o :只顯示被模式匹配到的字符串

-A #:after, 後#行

-B #: before, 前#行

-C #:context, 前後各#行

-c:顯示一個文件被匹配到幾行

-E :使用擴展正則表達式

-l:只列出匹配到的文件名

-L:列出不匹配的文件名,

grep -f file1 file2:顯示file2中包含file1中的行

元字符:

. :匹配任意單個字符

[ ] :匹配指定範圍內的任意單個字符

[^] :匹配指定範圍外的任意單個字符

[ - ]:範圍,如[A-Z],即A、B、C一直到Z都符合要求 。中括號裏有的都會被匹配上[a-z0-9]

字符集合:

[:digit:]數字,

[:lower:] 小寫字母,

[:upper:]大寫字母,

[:punct:]標點符號,

[:space:]空白,

[:alpha:]所有字母,

[:alnum:]包含所有數字的字母

[[::digit]]$ :匹配以1個數字結尾的行

[[:space:]][[::digit]]$ :匹配以1個數字,前面為空白為結尾的行

which ls|grep -v ‘^alias‘|grep -o ‘[^[:space:]]*‘ #

grep去掉行首,-o:只顯示被匹配到的

匹配次數:

* :匹配其前面字符任意次

.* :匹配任意長度的任意字符

\? :匹配其前面的字符1次或0次。前面需要加反斜線轉義,ls |grep "pas\?"

\+ :匹配前面字符至少一次

\{m,n\}:匹配其前面的字符至少m次,至多n次。ls |grep "pas\{1,2\}"

\{m\}:匹配前面的字符m次;

\{0,n\}:匹配前面的字符至多n次;

\{1,\} :匹配其前面的字符至少1次,

位置錨定:

^ :錨定行首,此字符後面的任意內容必須出現在行首

$ :錨定行尾,此字符後面的任意內容必須出現在行尾

^PATTERN$: 用於模式匹配整行;

^$ :空行。註意:空格不等於空行

\<或\b :錨定詞首,其後面的任意字符必須作為單詞首部出現

\>或\b :錨定詞尾,其前面的任意字符必須作為單詞的尾部出現

\<root\> :表示精確匹配root這個單詞,點號不算一個單詞裏面的字符

分組:

\(\):將一個或多個字符捆綁在一起,當作一個整體進行處理;

\(xy\)*ab

後向引用:引用前面的分組括號中的模式所匹配字符,(而非模式本身)

\1:從左側起,第一個左括號以及與之匹配右括號之間的模式所匹配到的字符;

\(ab\+\(xy\)*\):

\1: ab\+\(xy\)*

\2: xy

grep ‘\(l..e\).*\1‘ test.txt ##前面出現l..e,後面調用這個單詞,所以前後的一樣;

He love his lover. 匹配出現相同字段的行

He like his liker.

egrep :擴展正則表達式,grep -E:

+ :匹配其前面的字符至少1次,不能為0次

{m,n}:也表示至少m次,至多n次,但是不要加反斜線了

():分組,也支持\1,\2,….,

a|b :或者,表示or的意思,C|cat表示匹配C或者cat,(C|c)at

IPV4:5類,A,B,C,D,E

A:1-127 B:128-191 C:192-223

2.grep命令使用簡單實例

$ grep ‘test’ d* ##後可跟多個文件名,顯示所有以d開頭的文件中包含 test的行。

$ grep ‘[a-z]\{5\}’ aa

顯示所有包含每個字符串至少有5個連續小寫字符的字符串的行。

***默認情況下,’grep’只搜索當前目錄。如果 此目錄下有許多子目錄,’grep’會以如下形式列出:

grep: sound: Is a directory

這可能會使’grep’ 的輸出難於閱讀。這裏有兩種解決的辦法:

grep -r:明確要求搜索子目錄

grep -d skip:或忽略子目錄

$ grep magic /usr/src/Linux/Documentation/* | less 更方便閱讀

***命令行參數

grep -C number pattern files :匹配的上下文分別顯示[number]行,

grep pattern1 | pattern2 files :顯示匹配 pattern1 或 pattern2 的行,

grep pattern1 files | grep pattern2 :顯示既匹配 pattern1 又匹配 pattern2 的行。

***這裏還有些用於搜索的特殊符號:

grep ‘$‘ /etc/init.d/nfs.server | wc -l 統計一個文件共有多少行

grep ‘\<[Tt]he\>‘ size.txt 匹配單詞the,t或者T都可以

grep ‘[239].‘ data.doc #輸出所有含有以2,3或9開頭的,並且是兩個數字的行

grep ‘^[^48]‘ data.doc #不匹配行首是48的行

grep -E ‘219|216‘ data.doc #使用擴展模式匹配

ps -ef|grep svn -c 查看svn這個進程的個數

grep -nf test1.txt test2.txt 匹配test1.txt中包含test2.txt內容的行,並顯示行號

獲取本機ip:

# ifconfig |sed -n ‘s#^.*addr:\(.*\) Bcast.*#\1#gp‘

# ifconfig |grep "inet addr"|awk -F "[: ]+" ‘{print $4}‘ +代表重復一次或多次分隔符

# ifconfig |grep "inet addr"|cut -d ":" -f2|cut -d " " -f1

# ifconfig |awk -F "[: ]+" ‘NR==2 {print $4}‘ #用:或空格作為分隔且可重復多次

# ifconfig |sed -n ‘/inet addr/p‘|sed ‘s#^.*addr:##g‘|sed ‘s#Bcast:.*$##g‘

sed:

-n :使用安靜(silent)模式。只有經過sed 特殊處理的那一行(或者動作)才會被列出來。配合p

-e :替換時前面加-e,可替換多次,僅限於替換。用;也可實現

-f :直接將 sed 的動作寫在一個文件內, -f filename 則可以運行 filename 內的 sed 動作;

-r :支持擴展表達式,(默認是基礎正規表示法語法)

-i :直接修改讀取的文件內容,而不是輸出到終端。

function:

a :新增, a 的後面可以接字串,而這些字串會在新的一行出現(目前的下一行)~

i :插入, i 的後面可以接字串,而這些字串會在新的一行出現(目前的上一行);

c :取代, c 的後面可以接字串,這些字串可以取代 n1,n2 之間的行!

d :刪除,因為是刪除啊,所以 d 後面通常不接任何東東;

p :輸出匹配到並改動的行。通常 p 會與參數 sed -n 一起運行~

q:退出。sed -n ‘1p;2p;5p;5q‘ files。 5q:處理到第5行退出,不往下匹配

s :替換

&:表示匹配到的內容。echo ‘12345‘|sed -r ‘s/./&\n/g‘ file #把數字豎著打印出來

增加或插入單行內容:

sed -i ‘2a *****‘ person.txt #在第二行增加*****內容,a是追加的意思,在之後追加

sed -i ‘2i *****‘ person.txt #在原第二行之前插入*****內容,$為末尾,插到倒數第二行

添加多行:

sed ‘2a ****\n****‘ person.txt #這樣就可追加兩行,\n換行,

sed ‘2a **** \ #結尾為\,下面會自動顯示尖括號,再輸入第二行 內容

>*****‘ person.txtt

sed正則表達式用法:

10{sed-commands} ##對第10行操作

10,20{sed-commands} ##對第10到20行操作,包括10,20行

10,+20{sed-commands} ##對第10到30(10+20)行操作,包括10,30行

1~2{sed-commands} ##對1,3,5,7,….行操作,等差數列

10,${sed-commands} ##對10到最後一行($代表最後一行)操作,包括第10行

/oldboy/{sed-commands} ##區間操作,對匹配oldboy的行操作

/oldboy/,/Alex/{sed-commands} ##對匹配oldboy的行到匹配Alex的行操作

/oldboy/,${sed-commands} ##對匹配oldboy的行到最後一行操作

1,/Alex/{sed-commands} ##對第一行到匹配Alex的行操作

d:刪除指定的行,可用正則

sed ‘2d‘ person.txt ###指定刪除第二行

sed ‘N;$d‘ file #刪最後兩行。刪最後四行:cat file|sed ‘N;$d‘|sed ‘N;$d‘

cat 10|awk ‘NR==FNR{a++}NR!=FNR{if(FNR<=a-4)print $0}’ 10 10 #刪除後四行

cat 10|head -n -4 #顯示除了最後4行的全部行,-n:指定顯示前多少行,

sed ‘2,5d‘ person.txt

sed ‘1d;3d‘ file #刪除第一行和第三行

sed ‘3,$d‘ person.txt

sed ‘/=/!d‘ person.txt #!:取反,刪除沒被匹配到的,刪除不包括=號的行

sed ‘1~2d‘ person.txt ###刪除1,3,5,7…行

sed -r ‘/^$|[ \t]+/d‘ file #刪除空行和一個或多個空格加制位符的行,

sed ‘/zhangyao/d‘ person.txt #匹配到zhangyao的行刪掉,可用於打印不包含zhangyao的行

p:打印匹配行,-n:只顯示匹配到行

sed ‘2p‘ person.txt ###打印兩行

sed -n ‘2p‘ person.txt ###取消默認輸出

sed -n ‘1,3p‘ person.txt ###打印出1-3行

sed -n ‘1~2p‘ person.txt ###打印出1,3,5,7…行

sed -n ‘$=‘ file #顯示一個文件有幾行

sed -n ‘1p;3p‘ file ##;是中斷,只顯示第一和第三行,而不是1-3行

sed -n ‘/==*/p‘ file #匹配一個或多個=的行,等同於 sed -nr ‘/=+/p‘ file

用新行取代舊行:

sed ‘2c *****‘ person.txt ###把第二行的內容替換成*****

文本替換:

sed -i ‘s#guopeng#xiaoying#g‘

sed -i ‘3s#guopeng#xiaoying#g‘ ###指定行進行替換

sed -i ‘98,115s/#//g‘ nginx.conf ##去掉註釋

sed -i ‘98,117s/^/#/g‘ nginx.conf ##行首添加註釋

sed -n ‘/bash/{s/bash/blueshell/;p;q}‘ /etc/passwd

如果只替換/etc/passwd的第一個bash關鍵字為blueshell,就退出

sed -e ‘3,$d‘ -e ‘s/bash/blueshell/‘ /etc/passwd #一條sed語句,執行多種操作

sed ‘s/^/HEAD&/g‘ test.file ## 在每行的頭添加字符,比如"HEAD"

sed ‘s/$/&TAIL/g‘ test.file ##在每行的行尾添加字符,比如“TAIL”

sed引用外部變量:

sed "s/clone/$ip/g" file 等同於 sed ‘s/clone/‘$ip‘/g‘ #用雙引或變量加雙引

後向引用:

\U\1:把引用的\1內容變成大寫,upper的縮寫,\u:把首字母大寫,\L小寫

sed -r ‘s/(.*)([a-z]{3})(.*)/\3\U\2\1/g‘ file #把\2及之後的字母都變成大寫

ifconfig eth0|sed -n ‘s/^.*inet addr:\(.*\) Bcast:.*$/\1/g‘ 過濾ip

ifconfig|sed -rn ‘s/^.*inet addr:(.*) Bcast:.*$/\1/g‘p ##不同版本sed需要加p

ifconfig eth0|sed -n ‘s/^.*inet addr:\(.*\) Bcast:\(.*\) Mask.*$/\1\t\2/g‘ 多引用

-r 擴展正則表達式,用-r就不用加反斜線,不用轉義

# echo i am oldboy teacher.|sed ‘s#^.*am \([a-z].*\) tea.*$#\1#g‘

oldboy

# echo i am oldboy teacher.|sed -r ‘s#^.*am ([a-z].*) tea.*$#\1#g‘

oldboy

# chkconfig --list|grep "3:啟用"|grep -vE "sshd|crond|network|rsyslog|sysstat"|awk "{print $1}"|sed -r ‘s#^(.*)#chkconfig \1 off#g‘|bash

高級編輯命令:

h: 把模式空間中的內容覆蓋至保持空間中;

H:把模式空間中的內容追加至保持空間中;

g: 從保持空間取出數據覆蓋至模式空間;

G:從保持空間取出內容追加至模式空間;

x: 把模式空間中的內容與保持空間中的內容進行互換;

n: 讀取匹配到的行的下一行至模式空間;

N:追加匹配到的行的下一行至模式空間;

d: 刪除模式空間中的行;

D:刪除多行模式空間中的所有行;

sed -n ‘n;p‘ FILE:顯示偶數行

sed ‘n;d‘ FILE: 顯示奇數行;

sed ‘1!G;h;$!d‘ FILE:逆向顯示文件內容

sed -n ‘1!G;h;$p‘ FILE: 逆向顯示文件中的每一行;

sed ‘$!N;$!D‘ FILE: 取出文件後兩行;

sed ‘$!d‘ FILE:取出文件最後一行;

sed ‘G‘ FILE:

sed ‘/^$/d;G‘ FILE: 把多個空白行合並成一個空白行

AWK:

http://lizhenliang.blog.51cto.com/7876557/1892112?b4

-F:指明輸入時用到的字段分隔符

-v var=‘value‘ ##自定義變量

-F‘[: ]+‘ #以:號或空格一個或多個作為分隔符

-f:從文件中讀取awk程序源文件,tail -n3 /etc/services |awk -f test.awk

1.print pring $1,$2,...

1.逗號分隔符,用雙引號隔起來不做變量,

2.如省略item,相當於print $0:整行意思

3.‘print $1"\t"$2‘ #指定輸出分隔,"":讓輸出字段用什麽空格

2.變量:

內建變量:

FS:定義輸入文件分隔符, 默認都為空白字符

awk ‘BEGIN{FS=""}{print $1,$2}‘ file #取消分隔符,現在每個字符作為一個字段

OFS:定義輸出文件分隔符,默認都為空白字符

RS:指明輸入時使用的換行符

ORS:指明輸出時使用的換行符

NF:字段數,$NF:表示最後一個字段,$(NF-1)

echo "a b c d e f" |awk ‘{$NF="";$(NF-1)="";print$0}‘ 排除最後兩個字段:

NR:行數

awk ‘NR>1&&NR<4{print NR,$0}‘ #取出第二至第三行,並顯示行號

tail -n5 /etc/services |awk ‘NR==3{print $2}‘ 打印第三行第二個字段:

FNR:多文件分別統計行數,當FNR==NR時,說明在處理第一個文件內容,不等於時說明在處理

第二個文件內容。 一般FNR在處理多個文件時會用到

FILENAME:當前文件名

ARGC:命令行參數的個數

ARGV:數組,保存的是命令行所給定的各參數

awk -v FS=‘:‘ ‘{print $1}‘ /etc/passwd ##-v自定義變量FS,以:作為分隔符,再取第一段

awk -F: ‘{print $1}‘ /etc/passwd 也可以用-F然後接:,效果等同於自定義變量

awk -v FS=‘:‘ -v OFS=‘:‘ ‘{print $1,$3,$7}‘ /etc/passwd ##定義輸出以什麽作為分隔符,

awk ‘BEGIN{FS=":"}{print $1"#"$2}‘ /etc/passwd |head -n5 通過字符串拼接實現分隔:

awk ‘{print NF}‘ /etc/passwd 顯示每行有多少個字段,不需要加$符,

awk ‘BEGIN{print ARGC}‘ /etc/fstab

awk ‘BEGIN{print ARGV[0|1|2|...]}‘ /etc/fstab

自定義變量和引用外部變量:

1.引用外部變量,需用‘BEGIN{print ‘$+變量名‘}‘ 括起來,如不行,"‘ ‘" 用這種,同sed

2.-v:自定義變量或引用外部變量

awk -v a=$a ‘{print a}‘ 或 awk ‘{print ‘$a‘} ‘ #$a為引用bash變量,

awk -v test=‘hello gawk‘ ‘BEGIN{print test}‘ 等同於

awk ‘BEGIN{test=‘hello gawk‘;print test}‘

3.printf

格式化輸出:printf FORMAT,item1,item2,...

FORMAT:必須要給出

不會自動換行,需要顯示給出換行控制符:\n

FORMAT中需要分別為後面每個item指定一個格式化符號

格式符:

%c:顯示字符的ASCII碼

%d,%i:顯示十進制整數

%e,%E:科學計數法數值顯示

%f:顯示浮點數

%g,%G:以科學計數法胡浮點形式顯示數值

%s:顯示字符串

%u:無符號整數

%%:顯示%自身

awk -F: ‘{printf "Username:%s,UID:%d\n",$1,$3}‘ /etc/passwd #$1賦值%s上,$3賦值在%d上

修飾符:

#[.#]:第一個數字控制顯示的寬度,,第二個#表示小數點後的精度; %3.1f

-:左對齊。默認為右對齊

+:顯示數值的符號

4.操作符:

算數操作符:x+y,x-y,x*y,x^y,x%y,-x,+x

字符串操作符:沒有符號的操作符,字符串連接

賦值操作符:=,+=,-=,*=,/=,%=,^=,++,--

比較操作符:>,>=,<,<=,!=,==

模式匹配符:~(是否匹配),!~(是否不匹配)

awk ‘$2~/4567/{print $0}‘ #如果第二列匹配到4567,才執行後面的動作

awk ‘{if($2~/4567/){print $0}}‘ 等同於上

邏輯操作符:&& , || , !

seq 6 |awk ‘i=!i‘ 打印奇數行:

seq 6 |awk ‘!(i=!i)‘ 打印偶數行:

函數調用:function_name(argu1,argu2,...)

條件表達式:selector?if-true-expression:if-false-expression

在awk中,有3種情況表達式為假:數字是0,空字符串和未定義的值

awk ‘BEGIN{n=0;if(n)print"true";else print "false"}‘ 結果為:false

awk‘BEGIN{s="";if(s)print "true";else print"false"}‘ 結果為:false

awk‘BEGIN{if(s)print "true";else print "false"}‘ 結果為:false

seq 5 |awk ‘{print $0*2}‘ 乘法

seq 5 |awk ‘{print $0%2}‘ 取余

seq 5 |awk ‘$0%2==0{print $0}‘ 打印偶數行:

seq 5 |awk ‘$0%2!=0{print $0}‘ 打印奇數行

seq 5 |shuf |awk ‘{print$0|"sort"}‘ 管道符使用

例:

awk -F: ‘{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}‘ /etc/passwd

:作為分隔符,第三列大於等於1000就命名為Common User,小於1000的命名為Sysadmin or SysUser,%15s對應$1,%s對應usertype,\n換行,-s左對齊,%15默認為右對齊

5.模式匹配

1.empty:空模式,匹配每一行

2./regular expression/:僅處理能夠被此處的模式匹配到的行

awk ‘/^UUID/{print $1}‘ /etc/fstab centos 7的fstab文件以UUID開頭。

awk ‘!/^UUID/{print $1}‘ /etc/fstab 取反

tail /etc/services |awk ‘/^blp5/{print $0}‘ 匹配開頭是blp5的行:

tail /etc/services |awk ‘/^[a-z0-9]{8} /{print $0}‘ 匹配第一個字段是8個字符的行:

不匹配開頭是#和空行:

awk‘! /^#/ && ! /^$/{print $0}‘ /etc/httpd/conf/httpd.conf

awk‘! /^#|^$/‘ /etc/httpd/conf/httpd.conf

awk‘/^[^#]|"^$"/‘ /etc/httpd/conf/httpd.conf

3.relational expression:關系表達式: 結果有“真”有“假”:結果為"真"才會被處理

真:結果為非0值,非空字符串;

awk -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd

awk -F: ‘$NF=="/bin/bash"{print $1,$NF}‘ /etc/passwd

awk -F: ‘$NF"~/bash$/"{print $1,$NF}‘ /etc/passwd

以bash$為結尾的模式匹配,模式匹配要用//括起來

4.匹配行範圍:/path1/,/path2/

awk -F: ‘/^root/,/^nobody/{print $1}‘ /etc/passwd

匹配root起始的行到nobody開頭的行中間的行,取第一個字段值

awk -F: ‘(NR>=2&&NR<=10){print $1}‘ /etc/passwd

5.BEGIN/END模式:

BEGIN{}:還沒匹配第一行之前,先執行BEGIN的行為,用於變量賦值,輸出標頭

END{}:在文本處理完成之後執行END的語句,用於變量最終的輸出,取最後一行

cat 10.txt|awk ‘{a+=$1}END{print a}‘ #輸出1加到10的值,豎列

pa aux|awk ‘/\java/{a+=$3;b+=$4}END{print "cpu:"a" mem:"b}‘ #統計進程cpu和內存

awk -F: ‘BEGIN{print " username uid \n---------------------"}{print $1,$3}END{print "==========\n end"}‘ /etc/passwd

6.控制語句:

6.1:if-esle

語法:‘{if(condition) {statments} else {statments}}‘ 雙分支if語句

‘/^_/{if(***)print $0}‘ #if前面還可以接正則匹配過濾,在判斷

seq 5 |awk ‘{if($0==3)print $0;else print "no"}‘

awk‘{if($1==4){print "1"} else if($2==5){print "2"} elseif($3==6){print "3"} else {print "no"}}‘ file

awk -F: ‘{if($3>=1000) print $1,$3}‘ /etc/passwd

awk -F: ‘{if($NF=="/bin/bash") print $1}‘ /etc/passwd

awk -F: ‘{if($3>=1000) {printf "Common user:%s\n",$1} else {printf "root or SysUser:%s\n",$1}}‘ /etc/passwd centos 7是1000,centos 6是500

awk ‘{if(NF>5) print $0}‘ /etc/fstab 使用場景:對awk取得的整行或某個字段做條件判斷

df -h|awk -F[%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>=20)print $1}‘ 挑出dev使用率大於20的磁盤

6.2:while循環

語法:while(condition) statments

條件為“真”,進入循環,條件為“假”,退出循環

使用場景:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用

length() 計算長度函數

awk ‘/^[[:space:]]*linux16‘/{i=1;while(i<=NF) {print $i,length($i);i++}}‘ /etc/grub2.cfg

對每一行的每一個字段做單獨的統計

awk ‘/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)};i++}}‘ /etc/grub2.cfg while循環裏面再嵌套if語句

break跳過所有循環,continue跳過當前循環。

awk ‘BEGIN{for(i=1;i<=5;i++){if(i==3){break};print i}}‘

awk ‘BEGIN{for(i=1;i<=5;i++){if(i==3){continue};print i}}‘

exit退出程序,與shell的exit一樣。[ expr]是0-255之間的數字。

seq5 |awk ‘{if($0~/3/)exit (123)}‘

echo $?

123

6.3:do-while循環:至少執行一次循環體

6.4:for循環

語法:for (variable assignment;condition;iteration process) {for-body}

awk ‘/^[[:space:]]*linux16/{for (i=1;i<=NF;i++) {print $i,length($i)}}‘ /etc/grub2.cfg

awk ‘{for(i=1;i<=NF;i++){n++}}END{print n}‘ file #統計文件有多少個單詞,可用wc

n++:每循環一次就加1

awk ‘{for(i=1;i<=NF;i++){if($i=="60"){n++}}}END{print n}‘ file1 #統計有多少個60

df -h|awk -F‘[\t %]+‘ ‘{a=a+$5}END{print a}‘ #統計磁盤總使用率,豎列相加

特殊用法:能夠遍歷數組中的元素:

語法:for(var in array) {for-body}

6.5:switch語句:

switch(expression) {case VALUE1 or /REGEXP/: statement;case VALUE2 or /REGEXP2/: statement;...;default:statement;}

6.6 next:在行間執行,提前結束

awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd

如果$3項除2不等於0,就直接跳到下一行處理。

7.array:數組

關聯數組:array[index-expression]

index-expression:

1.可使用任意字符串,字符串要使用雙引號

2.如果某數組元素事先不存在,在引用時,awk會自動創建此元素,並將其值初始化為"空串"

若要判斷數組中是否存在某元素,要使用"index in array"格式進行

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";print weekdays["mon"]}‘

若要遍歷數組中的每個元素,要使用for循環。

註意:var會遍歷array的每個索引

state["LISTEN"]++ 此處LISTEN為下標

state["ESTABLISHED"]++

awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) print weekdays[i]}‘

netstat -tan|awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}‘

awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log ##計算訪問ip數量

awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}‘ /etc/fstab

##統計文件中每個文件出現的次數

去重三個方法:

awk ‘++a[$1]==1‘ file #同下面一行都是以最開始匹配到為基準,後面重復的忽略

awk ‘!a[$1]++‘ file #省略{print $0},對第4列去重就是$4

awk ‘{a[$1]=$0}END{for (i in a){print a[i]}}‘ #以最終的為基準,不斷賦值,

計數:

awk ‘{a[$1]+=1}END{for(i in a){print i,a[i]}}‘ file

例1:

cat file

a 1

a 2

b 3

b 4

cat file|awk ‘{a[$1]=a[$1]+$2}END{for(i in a){print i,a[i]}}‘ #計算多個a和多個b各自的值

a 3

b 7

處理多文件:

awk ‘NR==FNR{a[FNR]=$1}NR!=FNR{print a[FNR],$2}‘ file file1

把一個文件的第一列和另一個文件的第二列拼湊起來

NR==FNR:表示處理第一個文件。

NR!=FNR:表示處理第二個文件

處理多文件計數:

awk ‘{a[$1]=a[$1]+$2}END{for(i in a){print i,a[i]}}‘ file file1 file2

二維數組行列轉換:

awk ‘{for(i=1;i<=NF;i++){a[NR,i]=$i}}END{for(i=1;i<=NF;i++){for(j=1;j<=NR;j++){printf a[j,i]" "}print ""}}‘

修改第一列值:

cat file|awk ‘{$1=3}1‘ === cat file |awk ‘{$1=3;print $0}‘

兩個文件行中有相同字段,合並並且以file1為準,file1需放後面:

awk ‘NR==FNR{a[$1]=$0;next}NR!=FNR{$1=a[$1];print $0}‘ file2 file1


grep、sed、awk基礎