awk
awk的工作模式是掃描文件中的每一行森缠, 并且對符合條件的行進行處理楣富, 處理的時候可以針對整行寄疏, 也可以針對行里的每個域。
所以awk兩個最重要的參數(shù)就是:模式和動作灯荧, 根據(jù)模式找出符合條件的行礁击, 然后執(zhí)行指定的動作。
不指定模式的話默認就對于每一行都執(zhí)行動作逗载, 不指定動作的話默認就是把符合條件的行打印在屏幕上哆窿。
awk的語法
awk的語法如下
awk [options] 'pattern {action}' filename
或者
awk [options] -f script filename
第二種形式就是把'pattern {action}'
寫在了文件里。
options
是可選的厉斟, 最常用的有兩個:
-
-F seperator
挚躯,用來指定域的分隔符, 默認的分隔符是空格擦秽, 也就是每一個單詞是一個域码荔。可以指定多個域分隔符号涯,此時應該把多個與分隔符放置在方括號中目胡, 比如awk -F '[:-]' '{print $1,$3}' filename
, 使用:
或者-
作為域分隔符锯七, 并且打印出第一個和第三個域 -
-v var=value
,用來指定一個用戶自定義的變量链快, 可以稍后再pattern或者action中使用。
awk可以跟上多個pattern和action眉尸, 所以更一般的形式如下:
awk [options] 'pattern1 {action1} pattern2 {action2}...patternN {action}' filename
其中awk有內(nèi)置的兩個action域蜗, 叫做BEGIN
和END
,BEGIN在awk開始遍歷file的時候執(zhí)行,一般可以用來打印開始log或者定義在解析中用到的變量噪猾。 END在awk遍歷文件結(jié)束的時候執(zhí)行霉祸,一般用來打印結(jié)束的log.
所以awk的更一般的形勢是:
awk [options] 'BEGIN {action} patternN {actionN} END {action}' filename
務必要記住, 在awk的單引號中袱蜡, 所有的action都是在花括號中丝蹭, 在花括號外面的都是pattern,BEGIN和END可以看做是兩個特殊的pattern
花括號內(nèi)可以有多個操作坪蚁, 每個操作之間使用分號奔穿;分割, awk的操作支持使用所有的shell命令
awk的模式
awk的模式可以通過以下方式指定:
- 正則表達式,正則表達式一般都放在
/regular/
中間 - 關(guān)系表達式敏晤, 比如字符串或者數(shù)值大小的比較什么的
-
域 ~ 正則表達式
贱田,域 !~ 正則表達式
, 域或者變量符合或者不符合某個正則表達式嘴脾,~
和!~
分別表示域或者變量符合某個正則表達式或者不符合某個正則表達式 - 使用正則表達式指定的范圍男摧, 比如
/pattern1/,/pattern2/
awk內(nèi)置的環(huán)境變量, 只介紹最常用的
- $n 第n個域,默認是以空格分割的
- $0 當前完整的記錄耗拓,awk把每一個處理過的行都稱為一個記錄
- FILENAME 當前正在處理的文件的名稱
- NR number of record拇颅, 當前已經(jīng)處理過的記錄的個數(shù)
- NF number of field, 當前正在處理的記錄包含的域的個數(shù)
- FS field seperator域分隔符乔询, 默認為空格
- RS record seperator記錄分隔符蔬蕊, 默認為換行符
awk支持的運算符
awk支持編程語言中幾乎所有的運算符,+ - * / ++ -- > < <= >= != && || ! += -= *= /= ?:
包括但不局限于加減乘除哥谷, 自加自減岸夯, 邏輯與或非, 三目運算符等们妥。
還有兩個非常值得注意的運算符:
-
~ !~
匹配正則表達式和不匹配正則表達式 -
in
某個變量或者域是否屬于數(shù)組的成員
下面來看一個匹配和不匹配正則表達式操作符的例子
awk '$1 ~/^root/' filename
,打印出來第一個域以root開頭的所有記錄
下面看一些例子
-
awk '$1 + $3 >100' filename
打印所有第一個域和第三個域的和大于100的記錄 -
awk '/root/,/chico/' filename
打印第一個包含root的行和第一個包含chico的行中間的所有行 -
awk '/^(no|so)/' filename
打印所有以no或者so開頭的行 -
awk '/^(no|so)/ {print $2}' filename
打印所有以no或者so開頭的行的第二個域 -
awk '$1 ~ /[0-9][0-9]$/ {print $1}'filename
打印以兩個數(shù)字結(jié)尾的行的第一個域 -
awk '$1 >10 && $2 <30 {print $0}' filename
打印第一個域大于10并且第二個域小于30的所有行 -
awk '/^chicodong/{print $2}' filename
打印以chicodong開頭的行的第二個域
在看一點復雜的猜扮, 在awk中使用變量。
比如awk '$1 ~ /^test/ {count=$2+$3;print count}' filename
,count就是一個變量监婶,這個count=$1+$2
是賦值操作旅赢, 必須要放在action中。上面這個例子的含義是找出所有以test開頭的行惑惶, 并且打印出來第二個域和第三個域的和煮盼。
更改域的值
看下面一個例子
awk '{$2=$1+10; print $2}' filename
, 就是把第二個域的值更改為第一個域的值加10.
再看一個例子
awk '$1=="root"{$1="chico";print}' filename
,如果第一個域是root,那么就把第一個域改成chico,并且打印出來。
awk內(nèi)置的函數(shù)带污, 最常用的是printf僵控, 用來格式化輸出特別方便
echo "65"|awk '{print "%c\n", $0}'
, 可以打印出65對應的ASCII字符串。