久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Awk是什么

146次閱讀
沒有評論

共計 6475 個字符,預計需要花費 17 分鐘才能閱讀完成。

這篇文章主要介紹“Awk 是什么”的相關知識,丸趣 TV 小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Awk 是什么”文章能幫助大家解決問題。

什么是 Awk

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

我說它適用于服務器是因為日志文件,轉儲文件(dump files),或者任意文本格式的服務器終止轉儲到磁盤都會變得很大,并且在每個服務器你都會擁有大量的這類文件。如果你經歷過這樣的情境——在沒有像 Splunk 或者其他等價的工具情況下不得不在 50 個不同的服務器里分析幾 G 的文件,你會覺得去獲取和下載所有的這些文件并分析他們是一件很糟糕的事。

我親身經歷過這種情境。當一些 Erlang 節點將要死掉并留下一個 700MB 到 4GB 的崩潰轉儲文件(crash dump)時,或者當我需要在一個小的個人服務器(叫做 VPS)上快速瀏覽日志,查找一個常規模式時。

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

代碼結構

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

# comment

Pattern1 { ACTIONS; }

 

# comment

Pattern2 { ACTIONS; }

 

# comment

Pattern3 { ACTIONS; }

 

# comment

Pattern4 { ACTIONS; }

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

this is line 1
this is line 2

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

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

簡而言之,這就是 Awk 的運行模式

數據類型

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

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

最后,Awk 有數組類型,并且它們是動態的一維關聯數組。它們的語法是這樣的:var[key] = value。Awk 可以模擬多維數組,但無論怎樣,這是一個大的技巧(big hack)。

模式

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

正則表達式和布爾表達式

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

/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 部分執行。模式是專門匹配內容的。

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

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

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

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

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

{ACTIONS}

對輸入的每一行都將會簡單地執行 ACTIONS。

特殊的模式

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

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

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

最后一類模式,要把它進行歸類有點困難。它處于變量和特殊值之間,我們通常稱它們為域(Field)。而且名副其實。

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

# 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!

}

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

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

行為

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

{ 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  i++) { ACTION } }

{ for (item in c) { ACTION } }

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

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

函數

可以使用下面的語法來調用函數:

{somecall($2) }

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

用戶定義的函數同樣很簡單:

# 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;

}

特殊變量

除了常規變量(全局的,可以在任意地方使用),這里還有一系列特殊的變量,它們的的作用有點像配置條目(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 里,因為我更喜歡在那重寫它們。但是這些變量的重寫可以放在腳本的任意地方然后在后面的行里生效。

示例

以上的就是 Awk 語言的核心內容。我這里沒有大量的例子,因為我趨向于使用 Awk 來完成快速的一次性任務。

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

=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

產生下面的結果:

$ 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 進程里運行的函數列表,它們導致了 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) }

關于“Awk 是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注丸趣 TV 行業資訊頻道,丸趣 TV 小編每天都會為大家更新不同的知識點。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計6475字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 扬中市| 三明市| 徐汇区| 大宁县| 昌图县| 芦溪县| 景东| 铜陵市| 图木舒克市| 肇东市| 喜德县| 顺平县| 饶河县| 浦江县| 天全县| 双柏县| 梅州市| 游戏| 同江市| 赤峰市| 尼玛县| 嘉荫县| 科尔| 双辽市| 宣恩县| 炉霍县| 海淀区| 阿拉善右旗| 保定市| 平顺县| 巨鹿县| 二连浩特市| 石台县| 阳山县| 聂拉木县| 敖汉旗| 田东县| 从江县| 阳谷县| 涟水县| 涞源县|