awk入門學習筆記
來源:程序員人生 發布時間:2016-07-13 08:52:48 閱讀次數:2536次
零、awk的介紹
awk是Linux及Unix操作系統中非常優秀的數據及文本處理工具,它是1種編程語言。
主要用處是自動化運維和文本處理
1、awk基本語法
1、命令行格式:
awk -F' ' '{print $1}' pets.txt
awk -F '{print $1}' pets.txt(由于默許是空格,所以這類情況和上面的等效,但是我在嘗試的時候會報錯)
-F后面是指定的分隔符,:或' '
awk 'BEGIN{FS=" "}{print $1}' pets.txt
2、文本格式:
#!/usr/bin/awk
BEGIN{ FS=":"}
{print $1}
2、awk的變量
1、經常使用內置變量
$0 當前所有字段
$1~$n 當前第n個字段
FS 分隔符(默許為空格)
NF 字段個數
NR 行號
RS 輸入記錄的分隔符(默許為空格)
2、RS是指定的換行符,系統默許是\n進行換行,但是如果我們不希望使用\n而是使用自定義的換行符來進行分行,
那末只需要更改RS參數的值便可
awk 'BEGIN{RS=" "}{print $0}' pets.txt
3、NF是列數,如果我們需要打印每行依照我們指定的分隔方法有多少列,可以用以下命令調用
awk -F":" '{print NF}' /etc/passwd----------->輸出若干列7,代表文件中每行中以“:”作為分隔符都有7列。
4、NR是行號,如果我們需要給文件的每行加上1個固定的行號格式,例如 "1 : "的情勢,可使用以下語句
awk -F' ' '{print NR" : " $0}' pets.txt
5、調用外部變量
awk -v host=$HOSTNAME 'BEGIN{print host}'
也能夠自己定義變量名
awk -v host="host" 'BEGIN{print host}'
3、awk的操作符
關系操作符:<、>、<=、>=、==、!=、~ 、!~
1、依照指定要求匹配內容,如果我們需要匹配passwd文件中第7列是以/bin開頭的那些行,可以以下表示
awk -F: '$7 ~ /^\/bin/{print $0}' /etc/passwd
冒號分隔 ~代表匹配 ^代表字符串起始標志,匹配內容是/bin(注意后面還要帶1個/,否則會報錯)
那如果我們需要不匹配/bin開頭的行,只需要將~改成!~便可。
上述代碼也能夠用變量的情勢來替換
awk -F: -v reg='^/bin.*' '$7 ~ reg {print $0}' /etc/passwd
用1個正則表達式 reg來代替^/bin.*,然后再匹配第7列符合正則表達式的行并且返回
2、print與printf
如果要打印 /etc/passwd 中的“第1列 : 第2列”這類情勢的輸出,可以以下操作:
awk -F: '{print $1" : "$2}' /etc/passwd
如果要實現上述功能,可以用printf操作以下:
awk -F: '{printf("%s : %s\n",$1,$2)}' /etc/passwd
4、awk的流程控制
1、條件語句
格式:if(expression) action1;[else action2]
輸入1串數字,單數打印no,雙數打印yes,可以以下表示
seq 10|awk '{if($0%2==0){print "ok"}else {print "no"}}'
對文件操作,如果/etc/passwd最后1列是以/bin/bash結尾的,那末就打印整行的內容
awk -F: '{if($NF=="/bin/bash"){print $0}}' /etc/passwd
一樣可以不寫if語句加上1次判斷實現1樣的功能
awk -F: '$NF=="/bin/bash" {print $0}' /etc/passwd
2、循環語句
格式:while(condition) action
例:如果我們需要給每一個依照分隔符分開的列加上1個列號,如 1:第1列的內容 2:第2列的內容,.......
awk -F: '{i=1;while(i<=NF){printf(" %d:%s",i,$i);i++}{print " "}}' /etc/passwd
一樣也能用for循環完成一樣的功能
awk -F: '{for(i=1;i<=NF;i++){printf(" %d:%s",i,$i)}{print " "}}' /etc/passwd
例:需要統計最后1列的詞出現的頻數
awk -F: '{a[$NF]++}END{for(i in a){print i":"a[i]}}' /etc/passwd
3、awk數組
定義1個數組并且打印它
awk 'BEGIN{a[5]="Jack";a["name"]="Lilei";print a[5],a["name"]}'
一樣可以用循環來遍歷
awk_sed$ awk 'BEGIN{a[5]="Jack";a["name"]="Lilei";for(i in a)print i":"a[i]}'
netstat -an | awk '/^tcp/{state[$NF]++}END{for(key in state){print key"\t"state[key]}}'
5、awk函數
1、算術函數
awk的算術函數、字符串函數
int(x) 返回x的整數部份的值
sqrt(x) 返回x的平方根
rand() 返回偽隨機數r,其中0<=r<1
sand(x) 建立rand()新的種子數。如果沒有指定就用當天的時間。
隨機數示例:
awk 'BEGIN{print rand();srand();print rand()}'
2、字符串函數
sub(),gsub() 替換函數
index(s,t) 返回子串t在字符串s中的位置,如沒有則返回0。
length(s) 返回字符串長度,當沒有給出s時,返回$0的長度。
match(s,r) 如果正則表達式r在s中匹配到,則返回出現的起始位置,否則返回0
split(s,a,sep) 使用sep將字符串s分解到數組a中。默許sep為FS。
tolower(s) 將字符串s中的所有大寫字符轉換為小寫。
toupper(s) 將字符串s中的所有小寫字符轉換為大寫。
例:替換字符串中的某個單詞。將world換成China,
echo "hello world world" | awk '{sub("world","China");print $0}'
輸出: hello China world
上例只是替換了1個world,用gsub可以將所有的都進行替換
echo "hello world world" | awk '{gsub("world","China");print $0}'
輸出:hello China China
查找子串的位置
echo "hello world world" | awk '{print index($0,"world")}'
用指定分隔符分隔字符串
echo "00⑴1⑵2⑶3⑷4" |awk '{split($0,a,"-");for(i in a){print i":"a[i]}}'
3、自定義函數
自定義加法
awk 'function sum(n,m) {total=n+m;return total} BEGIN{print sum(1,2)}'
6、1些經常使用的操作
1、獲得本機的ip地址
ifconfig eth0 | awk -F':| +' '/inet addr:/{print $4}'
2、統計網絡連接數
netstat -an | awk '/^tcp/{state[$NF]++}END{for(key in state){print key"\t"state[key]}}' | column -t
3、在做訓練集的時候需要統計不同種別的散布的時候,可以有以下辦法(假定label放在最后,個人習慣):
cat test.txt | awk '{count[$NF]++}END{for(key in count){print key"\t"count[key]}}' | sort -k2 -n -r
或
awk '{print $NF}' test.txt | sort | uniq -c | sort -nr
test.txt的最后1列是label,統計它的label
4、將文件最后1列去掉
awk '{$NF="";print $0 >>"test.txt"}' 51job.txt
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈