三、awk 指令碼
四、awk 程式設計
五、寫在結尾
awk是linux上一款強大的文字分析工具,它可以將檔案逐行的讀入,然後用分割符分割開來,再對分割的各個部分進行處理。awk分割的各個部分叫做域,預設的分割符是空格和製表符。可以通過-f來指定分割符。
awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 awk 的 gnu 版本。
awk [引數] 'pattern'
awk的使用看起來比較複雜,但是掌握好它的語法後,其實也很簡單。
和大多數的命令一樣,awk可以指定一些引數,也可以不傳任何引數。awk具體支援哪些引數讀者可以通過man awk
檢視相關幫助文件。這裡就不多做介紹。
在引數後面跟著乙個單引號括起來的執行語句,其中pattern表示過濾規則,支援正規表示式和邏輯表示式。如果pattern涉及多個條件,可以用&&和||來關聯,分別表示與和或。pattern可以不填,表示不過濾任何資料。
pattern後面根據乙個花括號括起來的真正的執行語句,比如print $1
表示輸出分割後的第乙個域。action{}可以有多個語句,以;號隔開。如果缺失action則表示輸出一整行的內容。和以及效果一樣
假設有一段文字test.txt,有2個用逗號隔開的列,分別表示姓名、年齡。
jack,18
nick,24
joe,19
hack,19
輸出所有人的名字
awk -f , '' test.txt
-f ,
表示用逗號作為分割符,之後pattern為空,action則為
。awk執行後,每一行都會分割成兩列,之後輸出第一列的資料。其中$1則表示第一列的資料, $2則表示第二列的資料,以此類推,$n則表示第n列的資料。要注意的是,$0表示的是這一整行的資料。
輸出年齡小於20歲,並且名字中帶有ck內容的人(整行正則匹配)
awk -f , '/ck/ && $2
< 20' test.txt
輸出年齡小於20歲,並且名字中沒有帶有ck內容的人(整行正則匹配)
awk -f , '!/ck/ && $2
< 20' test.txt
上面用兩個斜槓//
圍起來的就是正規表示式,awk會對每行進行正則匹配,匹配不上的就不會進行處理。
由於直接使用//
匹配的是整行資料,所以如果我們的需求是要找名字中帶有ck內容的人的話,語句就不是很正確。因為如果這一行中剛好有其他欄位也包含了ck,那麼就可能造成誤匹配。那麼,怎麼就對名字這個字段進行正則匹配呢?
輸出年齡小於20歲,並且名字中帶有ck內容的人(就對名字的字段進行匹配)
awk -f , '$1 ~ /ck/ && $2
< 20' test.txt
$1 ~ //
則表示對第一列資料進行正則匹配,沒匹配上的列會被過濾。
$1 !~ //
則表示對第一列資料進行正則匹配,匹配上的列會被過濾。
指定多個分隔符
# 如果想指定多個分隔符,可以這樣
echo
"1;2,3.4"
|awk -f '[;,.]+'
''
action裡面的語句會對每一行過濾後的資料進行輸出,那麼,如果我們想在輸出的頭部和尾部增加一些內容,應該怎麼做呢?答案就是使用begin和end關鍵字。記得一定要大寫
begin後面跟乙個語句塊{}
,表示在awk掃瞄文字前輸出一些內容。end用法也一樣,在awk掃瞄文字後輸出一些內容。
awk -f , 'begin end ' test.txt
//輸出
name,age
jack,18
nick,24
joe,19
hack,19
end
上面的語句我們可以看到有3個{}
語句塊,分別表示掃瞄前語句塊,掃瞄文字時使用的語句塊,掃瞄後語句塊。
argc 命令列引數個數
argv 命令列引數排列
environ 支援佇列中系統環境變數的使用
filename awk瀏覽的檔名
fnr 瀏覽檔案的記錄數,也就是記錄所在的行數
fs 設定輸入域分隔符,等價於命令列 -f選項
nf 瀏覽記錄的域的個數
nr 已讀的記錄數
ofs 輸出域分隔符
ors 輸出記錄分隔符
rs 控制記錄分隔符
awk內建了一些變數,我們可以在語句塊直接使用 。
直接輸出第2行的資料
awk -f , 'fnr==2 ' test.txt
awk中同時提供了print和printf兩種列印輸出的函式。
其中print函式的引數可以是變數、數值或者字串。字串必須用雙引號引用括起來,引數必須用逗號分隔,不然多個引數之間連在一起會造成混淆。
printf和c語言中的printf基本一樣,可以格式化字串。
print輸出例子
awk -f , '' test.txt
printf輸出例子
awk -f , '' test.txt
//輸出
name=jack,age=18.00
name=nick,age=24.00
name=joe,age=19.00
name=hack,age=19.00
通過printf,我們可以將年齡轉化成小數點
通過-f scriptfile
來將awk執行語句放到指令碼中。我們可以編寫乙個awk指令碼test.awk
。
begin
$2< 20 && /ck/
end
之後執行
awk -f , -f test.awk test.txt
等同於執行
awk -f , 'begin $2
< 20 && /ck/ end '
awk指令碼也可以這麼寫
#!/usr/bin/awk -f
begin
$2< 20 && /ck/
end
之後直接執行該指令碼即可
./test.awk -f , test.txt
awk語句中可以直接定義變數然後使用
# 設定count變數,統計一共有多少行
awk -f , ' end ' test.txt
# 設定count變數的初始值為1
awk -f , 'begin end ' test.txt
我們可以在begin語句塊中設定變數的初始值,如果print要輸出乙個沒有定義過的變數,awk也不會報錯,而是輸出空字串。
awk的條件語句也和c語言基本一樣。
# 如果歲數小於20歲並且名字字段帶有ck,輸出的歲數就+5,否則就+1
awk -f , 'else}' test.txt
上面的語句就是我們常見的if…else,很好理解。
awk的迴圈語句也和c語言基本一樣。支援while、do/while、for、break、continue這些關鍵字。
# 每一行重複輸出3次
awk -f, 'begin ;i=0}' test.txt
awk -f, '}' test.txt
awk的陣列的下標可以是數字或者字母,這和js的map比較像。
# 輸出的過程中,遇到名字是nick的,把它的名字轉換成 hello 。最後我們再輸出乙個world
awk -f, 'begin else} end' test.txt
上面的語句在begin塊中定義了nickname的陣列,同時使用了兩種下標,分別是"nick"和數字1。之後在後面也用到了。
當然,要深入的學習awk肯定不是一件簡單的事,本篇部落格也只是對awk的語句進行一些簡單的介紹,也足以應付我們工作中大部分的需求。如果想深入學習awk的同學可以去官方文件學習看看。
linux命令 awk學習
我們在面試中經常被問到的linux命令 就都會包括awk命令的使用,下面我向大家總結awk命令的詳細使用。希望能給大家一些幫助。在國內很多大型公司面試後台程式設計師的時候無一例外都會問到下面這個題目 請統計某個apache或者nginx 內的log檔案,並求出裡面ip數的top10 當然,這個問題不...
LInux 命令awk學習
一 實現的功能 現有倆個檔案a.txt 裡邊有倆列資料 bid,name b.txt 好幾列資料 bid,pv 其中a.txt有3800w的資料量,b.txt有1300w的資料量,而且a.txt的資料報含b.txt的資料,要將b.txt的資料在a.txt裡邊刪除掉,並且還要給b.txt的bid 對應...
awk命令學習
題目 檔案a,每行兩列,格式為url ip,檔案b每行一列,格式為url,通過awk實現找出b檔案中的url是否在a檔案中,如存在,將此url和對應的ip輸出 檔案大小不考慮 編寫檔案a如下 編寫檔案b如下 預期輸出結果為 設計awk命令如下 c sharp view plain copy prin...