日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Awk 20 分钟入门介绍

發(fā)布時(shí)間:2024/3/24 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Awk 20 分钟入门介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是Awk

?

Awk是一種小巧的編程語言及命令行工具。(其名稱得自于它的創(chuàng)始人Alfred Aho、Peter Weinberger 和 Brian Kernighan姓氏的首個(gè)字母)。它非常適合服務(wù)器上的日志處理,主要是因?yàn)锳wk可以對文件進(jìn)行操作,通常以可讀文本構(gòu)建行。

?

我說它適用于服務(wù)器是因?yàn)槿罩疚募?#xff0c;轉(zhuǎn)儲文件(dump files),或者任意文本格式的服務(wù)器終止轉(zhuǎn)儲到磁盤都會(huì)變得很大,并且在每個(gè)服務(wù)器你都會(huì)擁有大量的這類文件。如果你經(jīng)歷過這樣的情境——在沒有像Splunk或者其他等價(jià)的工具情況下不得不在50個(gè)不同的服務(wù)器里分析幾G的文件,你會(huì)覺得去獲取和下載所有的這些文件并分析他們是一件很糟糕的事。

?

我親身經(jīng)歷過這種情境。當(dāng)一些Erlang節(jié)點(diǎn)將要死掉并留下一個(gè)700MB到4GB的崩潰轉(zhuǎn)儲文件(crash dump)時(shí),或者當(dāng)我需要在一個(gè)小的個(gè)人服務(wù)器(叫做VPS)上快速瀏覽日志,查找一個(gè)常規(guī)模式時(shí)。

?

在任何情況下,Awk都不僅僅只是用來查找數(shù)據(jù)的(否則,grep或者ack已經(jīng)足夠使用了)——它同樣使你能夠處理數(shù)據(jù)并轉(zhuǎn)換數(shù)據(jù)。

?

代碼結(jié)構(gòu)

?

Awk腳本的代碼結(jié)構(gòu)很簡單,就是一系列的模式(pattern)和行為(action):

?

# comment

Pattern1?{?ACTIONS;?}

?

# comment

Pattern2?{?ACTIONS;?}

?

# comment

Pattern3?{?ACTIONS;?}

?

# comment

Pattern4?{?ACTIONS;?}

?

掃描文檔的每一行時(shí)都必須與每一個(gè)模式進(jìn)行匹配比較,而且一次只匹配一個(gè)模式。那么,如果我給出一個(gè)包含以下內(nèi)容的文件:

?

this is line 1
this is line 2

?

this is line 1 這行就會(huì)與Pattern1進(jìn)行匹配。如果匹配成功,就會(huì)執(zhí)行ACTIONS。然后this is line 1 會(huì)和Pattern2進(jìn)行匹配。如果匹配失敗,它就會(huì)跳到Pattern3進(jìn)行匹配,以此類推。

?

一旦所有的模式都匹配過了,this is line 2 就會(huì)以同樣的步驟進(jìn)行匹配。其他的行也一樣,直到讀取完整個(gè)文件。

?

簡而言之,這就是Awk的運(yùn)行模式

?

數(shù)據(jù)類型

?

Awk僅有兩個(gè)主要的數(shù)據(jù)類型:字符串和數(shù)字。即便如此,Awk的字符串和數(shù)字還可以相互轉(zhuǎn)換。字符串能夠被解釋為數(shù)字并把它的值轉(zhuǎn)換為數(shù)字值。如果字符串不包含數(shù)字,它就被轉(zhuǎn)換為0.

?

它們都可以在你代碼里的ACTIONS部分使用 = 操作符給變量賦值。我們可以在任意時(shí)刻、任意地方聲明和使用變量,也可以使用未初始化的變量,此時(shí)他們的默認(rèn)值是空字符串:“”。

?

最后,Awk有數(shù)組類型,并且它們是動(dòng)態(tài)的一維關(guān)聯(lián)數(shù)組。它們的語法是這樣的:var[key] = value 。Awk可以模擬多維數(shù)組,但無論怎樣,這是一個(gè)大的技巧(big hack)。

?

模式

?

可以使用的模式分為三大類:正則表達(dá)式、布爾表達(dá)式和特殊模式。

?

正則表達(dá)式和布爾表達(dá)式

?

你使用的Awk正則表達(dá)式比較輕量。它們不是Awk下的PCRE(但是gawk可以支持該庫——這依賴于具體的實(shí)現(xiàn)!請使用 awk
–version查看),然而,對于大部分的使用需求已經(jīng)足夠了:

?

/admin/?{?...?}?# any line that contains 'admin'

/^admin/?{?...?}?# lines that begin with 'admin'

/admin$/?{?...?}?# lines that end with 'admin'

/^[0-9.]+ /?{?...?}?# lines beginning with series of numbers and periods

/(POST|PUT|DELETE)/?# lines that contain specific HTTP verbs

?

注意,模式不能捕獲特定的組(groups)使它們在代碼的ACTIONS部分執(zhí)行。模式是專門匹配內(nèi)容的。

?

布爾表達(dá)式與PHP或者Javascript中的布爾表達(dá)式類似。特別的是,在awk中可以使用&&(“與”)、||(“或”)、!(“非”)操作符。你幾乎可以在所有類C語言中找到它們的蹤跡。它們可以對常規(guī)數(shù)據(jù)進(jìn)行操作。

?

與PHP和Javascript更相似的特性是比較操作符,==,它會(huì)進(jìn)行模糊匹配(fuzzy matching)。因此“23”字符串等于23,”23″ == 23 表達(dá)式返回true。!= 操作符同樣在awk里使用,并且別忘了其他常見的操作符:>,<,>=,和<=。

你同樣可以混合使用它們:布爾表達(dá)式可以和常規(guī)表達(dá)式一起使用。 /admin/ || debug == true 這種用法是合法的,并且在遇到包含“admin”單詞的行或者debug變量等于true時(shí)該表達(dá)式就會(huì)匹配成功。

?

注意,如果你有一個(gè)特定的字符串或者變量要與正則表達(dá)式進(jìn)行匹配,~ 和!~ 就是你想要的操作符。 這樣使用它們:string ~ /regex/ 和 string !~ /regex/。

同樣要注意的是,所有的模式都只是可選的。一個(gè)包含以下內(nèi)容的Awk腳本:

{ ACTIONS }

?

對輸入的每一行都將會(huì)簡單地執(zhí)行ACTIONS。

?

特殊的模式

?

在Awk里有一些特殊的模式,但不是很多。

?

第一個(gè)是BEGIN,它僅在所有的行都輸入到文件之前進(jìn)行匹配。這是你可以初始化你的腳本變量和所有種類的狀態(tài)的主要地方。

?

另外一個(gè)就是END。就像你可能已經(jīng)猜到的,它會(huì)在所有的輸入都被處理完后進(jìn)行匹配。這使你可以在退出前進(jìn)行清除工作和一些最后的輸出。

?

最后一類模式,要把它進(jìn)行歸類有點(diǎn)困難。它處于變量和特殊值之間,我們通常稱它們?yōu)橛?#xff08;Field)。而且名副其實(shí)。

?

?

使用直觀的例子能更好地解釋域:

?

# According to the following line

#

# $1 $2 $3

# 00:34:23 GET /foo/bar.html

# _____________ _____________/

# $0

?

# Hack attempt?

/admin.html$/ &&?$2?==?"DELETE"?{

print?"Hacker Alert!";

}

?

域(默認(rèn)地)由空格分隔。$0 域代表了一整行的字符串。 $1 域是第一塊字符串(在任何空格之前), $2 域是后一塊,以此類推。

?

一個(gè)有趣的事實(shí)(并且是在大多是情況下我們要避免的事情),你可以通過給相應(yīng)的域賦值來修改相應(yīng)的行。例如,如果你在一個(gè)塊里執(zhí)行 $0 = “HAHA THE LINE IS GONE”,那么現(xiàn)在下一個(gè)模式將會(huì)對修改后的行進(jìn)行操作而不是操作原始的行。其他的域變量都類似。

?

行為

?

這里有一堆可用的行為(possible actions),但是最常用和最有用的行為(以我的經(jīng)驗(yàn)來說)是:

?

{?print?$0;?}?# prints $0. In this case, equivalent to 'print' alone

{?exit;?}?# ends the program

{?next;?}?# skips to the next line of input

{?a=$1;?b=$0?}?# variable assignment

{?c[$1]?=?$2?}?# variable assignment (array)

?

{?if?(BOOLEAN)?{?ACTION?}

else?if?(BOOLEAN)?{?ACTION?}

else?{?ACTION?}

}

{?for?(i=1;?i<x;?i++)?{?ACTION?}?}

{?for?(item?in?c)?{?ACTION?}?}

?

這些內(nèi)容將會(huì)成為你的Awk工具箱的主要工具,在你處理日志之類的文件時(shí)你可以隨意地使用它們。

?

Awk里的變量都是全局變量。無論你在給定的塊里定義什么變量,它對其他的塊都是可見的,甚至是對每一行都是可見的。這嚴(yán)重限制了你的Awk腳本大小,不然他們會(huì)造成不可維護(hù)的可怕結(jié)果。請編寫盡可能小的腳本。

?

函數(shù)

?

可以使用下面的語法來調(diào)用函數(shù):

?

{ somecall($2) }

?

這里有一些有限的內(nèi)置函數(shù)可以使用,所以我可以給出這些函數(shù)的通用文檔(regular documentation)。

?

用戶定義的函數(shù)同樣很簡單:

?

# function arguments are call-by-value

function?name(parameter-list)?{

ACTIONS;?# same actions as usual

}

?

# return is a valid keyword

function?add1(val)?{

return?val+1;

}

?

特殊變量

?

除了常規(guī)變量(全局的,可以在任意地方使用),這里還有一系列特殊的變量,它們的的作用有點(diǎn)像配置條目(configuration entries):

?

BEGIN?{?# Can be modified by the user

FS?=?",";?# Field Separator

RS?=?"n";?# Record Separator (lines)

OFS?=?" ";?# Output Field Separator

ORS?=?"n";?# Output Record Separator (lines)

}

{?# Can't be modified by the user

NF?# Number of Fields in the current Record (line)

NR?# Number of Records seen so far

ARGV?/?ARGC?# Script Arguments

}

?

我把可修改的變量放在BEGIN里,因?yàn)槲腋矚g在那重寫它們。但是這些變量的重寫可以放在腳本的任意地方然后在后面的行里生效。

?

示例

?

以上的就是Awk語言的核心內(nèi)容。我這里沒有大量的例子,因?yàn)槲亿呄蛴谑褂肁wk來完成快速的一次性任務(wù)。

?

不過我依然有一些隨身攜帶的腳本文件,用來處理一些事情和測試。我最喜歡的一個(gè)腳本是用來處理Erlang的崩潰轉(zhuǎn)儲文件,形如下面的:

?

=erl_crash_dump:0.3

Tue?Nov?18?02:52:44?2014

Slogan:?init terminating?in?do_boot?()

System?version:?Erlang/OTP?17?[erts-6.2]?[source]?[64-bit]?[smp:8:8]?[async-threads:10]?[hipe]?[kernel-poll:false]

Compiled:?Fri?Sep?19?03:23:19?2014

Taints:

Atoms:?12167

=memory

total:?19012936

processes:?4327912

processes_used:?4319928

system:?14685024

atom:?339441

atom_used:?331087

binary:?1367680

code:?8384804

ets:?382552

=hash_table:atom_tab

size:?9643

used:?6949

...

=allocator:instr

option?m:?false

option?s:?false

option?t:?false

=proc:<0.0.0>

State:?Running

Name:?init

Spawned?as:?otp_ring0:start/2

Run?queue:?0

Spawned?by:?[]

Started:?Tue?Nov?18?02:52:35?2014

Message queue?length:?0

Number of heap?fragments:?0

Heap fragment?data:?0

Link?list:?[<0.3.0>,?<0.7.0>,?<0.6.0>]

Reductions:?29265

Stack+heap:?1598

OldHeap:?610

Heap?unused:?656

OldHeap?unused:?468

Memory:?18584

Program?counter:?0x00007f42f9566200?(init:boot_loop/2?+?64)

CP:?0x0000000000000000?(invalid)

=proc:<0.3.0>

State:?Waiting

...

=port:#Port<0.0>

Slot:?0

Connected: <0.3.0>

Links: <0.3.0>

Port controls?linked-in?driver:?efile

=port:#Port<0.14>

Slot:?112

Connected: <0.3.0>

...

?

產(chǎn)生下面的結(jié)果:

?

$?awk?-f?queue_fun.awk?$PATH_TO_DUMP

MESSAGE QUEUE?LENGTH:?CURRENT?FUNCTION

======================================

10641:?io:wait_io_mon_reply/2

12646:?io:wait_io_mon_reply/2

32991:?io:wait_io_mon_reply/2

2183837:?io:wait_io_mon_reply/2

730790:?io:wait_io_mon_reply/2

80194:?io:wait_io_mon_reply/2

...

?

這是在Erlang進(jìn)程里運(yùn)行的函數(shù)列表,它們導(dǎo)致了mailboxe變得很龐大。腳本在這:

?

# Parse Erlang Crash Dumps and correlate mailbox size to the currently running

# function.

#

# Once in the procs section of the dump, all processes are displayed with

# =proc:<0.M.N> followed by a list of their attributes, which include the

# message queue length and the program counter (what code is currently

# executing).

#

# Run as:

#

# $ awk -v threshold=$THRESHOLD -f queue_fun.awk $CRASHDUMP

#

# Where $THRESHOLD is the smallest mailbox you want inspects. Default value

# is 1000.

BEGIN?{

if?(threshold?==?"")?{

threshold?=?1000?# default mailbox size

}

procs?=?0?# are we in the =procs entries?

print?"MESSAGE QUEUE LENGTH: CURRENT FUNCTION"

print?"======================================"

}

?

# Only bother with the =proc: entries. Anything else is useless.

procs?==?0?&& /^=proc/?{?procs?=?1?}?# entering the =procs entries

procs?==?1?&& /^=/ && !/^=proc/?{?exit?0?}?# we're done

?

# Message queue length: 1210

# 1 2 3 4

/^Message queue?length: / &&?$4?>=?threshold?{?flag=1;?ct=$4?}

/^Message queue?length: / &&?$4?<?threshold?{?flag=0?}

?

# Program counter: 0x00007f5fb8cb2238 (io:wait_io_mon_reply/2 + 56)

# 1 2 3 4 5 6

flag?==?1?&& /^Program?counter: /?{?print?ct?":",?substr($4,2)?}

?

你跟上思路沒?如果跟上了,你已經(jīng)了解了Awk。恭喜!

?

來源:伯樂在線?-?周進(jìn)林

轉(zhuǎn)載于:https://my.oschina.net/u/3100313/blog/886049

總結(jié)

以上是生活随笔為你收集整理的Awk 20 分钟入门介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。