awk入門(二)

本文的使用的示例文件

~]$ cat a.txt
ID  name    gender  age  email          phone
1   Bob     male    28   [email protected]     18023394012
2   Alice   female  24   [email protected]  18084925203
3   Tony    male    21   [email protected]    17048792503
4   Kevin   male    21   [email protected]    17023929033
5   Alex    male    18   [email protected]    18185904230
6   Andy    female  22   [email protected]    18923902352
7   Jerry   female  25   [email protected]  18785234906
8   Peter   male    20   [email protected]     17729348758
9   Steven  female  23   [email protected]    15947893212
10  Bruce   female  27   [email protected]   13942943905

修改字段或NF產生的聯動效應

1.在使用awk進行輸出時,如果修改了字段的值或者修改了變量NF,那麼awk在輸出的時候就會重新以OFS爲間隔輸出每條記錄。
2.OFS可以自定義設置,如果不設置則默認爲空格。
3.如果先修改字段或者NF,然後才設置OFS,那麼第一行就不會以新設置的OFS爲間隔,而是以默認的空格爲間隔
4.使用$0=$0不能導致重新劃分字段
想要重建之後的所有行都生效,那麼最好先設置OFS再進行重建

~]$ awk '{$1=$1;print $0}' a.txt  ##這樣輸出其實對文件已經產生了修改,OFS從製表符變成了空格
~]$ awk '{OFS="*";$1=$1;print $0}' a.txt ##這樣就會以*號爲間隔重新輸出每一條記錄
~]$ awk '{$1=$1;OFS="*";print $0}' a.txt ##這樣設置,第一行的間隔仍然是以空格爲準的,因爲先設置的$1=$1,
										 ##所以已經導致了當前行的重建,因此間隔符仍然以默認的爲準
~]$ awk '{OFS="*";NF=1;print $0}' a.txt  ##設置NF的值爲1,導致$0重建,不過輸出時也只有第一列數據
~]$ awk '{OFS="*";NF-=2;print $0}' a.txt ##NF修改導致$0重建
~]$ awk '{OFS="*";$(NF+2)=5;print $0}' a.txt ##這樣會新產生一個字段,並且該字段的值爲5,這樣也會產生$0重建

示例

使用$0重建來壓縮文件中的空格
~]$ echo "a   b c         d    e     " | awk '{$1=$1;print $0}'
~]$ echo "a   b c         d    e     " | awk '{$1=$1;print $0}' OFS="-"

awk數據篩選

1.按記錄篩選
2.按字段篩選
3.按正則表達式篩選
4.定址的方式篩選
5.多條件組合篩選

1.按記錄篩選,可以根據NR變量來進行判斷,從而篩選指定的記錄號
~]$ awk 'NR==3{print $1,$2,$3}' a.txt ##這樣就可以只輸出第三條記錄中響應的字段了
2.按字段篩選
~]$ awk 'NR==1{print $1}' a.txt ##只輸出第一條記錄的第一個字段
~]$ awk '($1+0)>5{print $2}' a.txt ##將$1隱性轉換到整型,然後篩選$1字段大於5的記錄,並且輸出$2字段
~]$ awk '$2 ~ /\A.*x\>/{print $6}' a.txt ##篩選$2字段滿足此正則表達式的記錄,並且輸出該記錄的$6字段
3.使用正則表達式匹配
~]$ awk '/Alice/{print $0}' a.txt
~]$ awk '/A.*/{print $0}' a.txt
~]$ awk '/A.*y/{print $0}' a.txt
~]$ awk '/A[[:alpha:]]+y/{print $0}' a.txt
~]$ awk '/\<A.*y\>/{print $0}' a.txt  ##使用正則表達式最爲靈活,可以根據需要靈活使用
4.定址
~]$ awk 'NR==1 || NR==3{print $1}' a.txt ##若記錄數是第一或第三條記錄,那麼就輸出該記錄的$1字段
~]$ awk 'NR==1,NR==3{print $0}' a.txt ##輸出前三條記錄
~]$ awk 'NR==1,$6 ~ /170*/{print $0}' a.txt  ##輸出從第一條記錄開始到$6字段以170開頭的記錄
5.多條件組合篩選,以上示例中很多都是多條件組合篩選的
~]$ awk '$1 > 3 && $3 ~ /female/{print $2}' a.txt

示例

篩選ifconfig命令結果中除lo網卡之外的所有網卡的ip地址:本文僅討論awk的篩選方式,其他方式暫不討論
方式一:
	~]$ ifconfig | awk 'BEGIN{RS="^$"}{print $6}'
方式二:
	~]$ ifconfig | awk '/inet / && !/127.*/{print $2}'
方式三:
	~]$ ifconfig | awk 'BEGIN{RS="";FS="\n"}NR==1{$0=$2;FS=" ";$0=$0;print $2}' ##通過字段重建的方式來篩選

awk工作流程

1.解析 -v var1=value…中的變量聲明
2.編譯awk源代碼爲awk可解釋的內部各式,包括-v變量
3.執行BEGIN代碼段
4.根據RS來讀取文件,如果沒有指定文件,那麼就從標準輸入中讀取文件,同時執行main代碼段:

  • 如果在文件名部分聲明變量,此階段的變量在BEGIN之後聲明的,因此此變量在BEGIN段中不可用,在main段中可用
  • 每讀取一條記錄:
    (1)都將設置NR,FNR,RT,$0等變量
    (2)根據FS切割每條記錄的字段,並保存至$1,$2,$3…等變量中
    (3)測試main代碼段中的pattern部分,測試成功則執行action部分,pattern可以有多個,每個未聲明action的pattern都有一個默認action,此默認action爲{print $0}。

5.執行END代碼段

~]$ awk 'BEGIN{print "hello"}{print $0}END{print "end"}' a.txt ##這樣就會在每個記錄之前輸出“hello”,
## 在輸出每條記錄後輸出出“end”,另外hello和end需要雙引號包圍,不然awk當做變量處理,從而輸出爲空行
hello
ID  name    gender  age  email          phone
end
1   Bob     male    28   [email protected]     18023394012
end
2   Alice   female  24   [email protected]  18084925203
end
3   Tony    male    21   [email protected]    17048792503
end
4   Kevin   male    21   [email protected]    17023929033
end
5   Alex    male    18   [email protected]    18185904230
end
6   Andy    female  22   [email protected]    18923902352
end
7   Jerry   female  25   [email protected]  18785234906
end
8   Peter   male    20   [email protected]     17729348758
end
9   Steven  female  23   [email protected]    15947893212
end
10  Bruce   female  27   [email protected]   13942943905
end
發佈了38 篇原創文章 · 獲贊 1 · 訪問量 1241
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章