grep、sed、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:]]*‘ #用
匹配次數:
* :匹配其前面字符任意次
.* :匹配任意長度的任意字符
\? :匹配其前面的字符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基礎