一天一個shell命令 linux文本內(nèi)容操作系列-awk命令詳解
簡介
awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數(shù)據(jù)分析并生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。
awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名稱得自于它的創(chuàng)始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。實際上 AWK 的確擁有自己的語言: AWK 程序設計語言 , 三位創(chuàng)建者已將它正式定義為“樣式掃描和處理語言”。它允許您創(chuàng)建簡短的程序,這些程序讀取輸入文件、為數(shù)據(jù)排序、處理數(shù)據(jù)、對輸入執(zhí)行計算以及生成報表,還有無數(shù)其他的功能。
使用方法
awk '{pattern + action}' {filenames}
盡管操作可能會很復雜,但語法總是這樣,其中 pattern 表示 AWK 在數(shù)據(jù)中查找的內(nèi)容,而 action 是在找到匹配內(nèi)容時所執(zhí)行的一系列命令?;ɡㄌ枺▄})不需要在程序中始終出現(xiàn),但它們用于根據(jù)特定的模式對一系列指令進行分組。 pattern就是要表示的正則表達式,用斜杠括起來。
awk語言的最基本功能是在文件或者字符串中基于指定規(guī)則瀏覽和抽取信息,awk抽取信息后,才能進行其他文本操作。完整的awk腳本通常用來格式化文本文件中的信息。
通常,awk是以文件的一行為處理單位的。awk每接收文件的一行,然后執(zhí)行相應的命令,來處理文本。
調(diào)用awk
有三種方式調(diào)用awk
說明:
awk被設計用于數(shù)據(jù)流,能夠?qū)α泻托羞M行操作。而sed更多的是匹配,進行替換和刪除。
awk有很多內(nèi)建的功能,比如數(shù)組,函數(shù)等。靈活性是awk的最大優(yōu)勢。
awk的結(jié)構(gòu)
awk '
BEGIN{ print "start"}
pattern { commands }
END{ print "end"}'
file
為了偏于觀看,我打了回車,實際上是一行
一個awk腳本通常是3部分
1. BEGIN語句塊
2. 能夠使用模式匹配的通用語句塊
3. END語句塊
他們?nèi)魏我徊糠侄伎梢圆怀霈F(xiàn)在腳本中。腳本通常包含在雙引號或者單引號內(nèi)。
例如:
awk 'BEGIN{i=0}{i++}END{print i}' filename
工作原理
awk命令的工作方式如下:
1. 執(zhí)行BEGIN{commands}語句塊中的語句
2. 從文件或者stdin中讀取一行,然后執(zhí)行pattern{commands}. 迭代直到全部讀取完畢
3. 最后執(zhí)行END{commands}語句塊
再次提醒,他們?nèi)魏我徊慷伎梢詻]有
而awk的功能也遠不止如此
入門實例:
echo | awk '{var1="v1";var2="v2";var3="v3"; print var1,var2,var3;}'
打印: v1 v2 v3
解釋:逗號為定界符(分隔符)
echo | awk '{var1="v1";var2="v2";var3="v3"; print var1"-"var2"-"var3;}'
打印v1-v2-v3
解釋:雙引號為連接符
其他任何符號,都不能正常輸出v1,v2,v3
解讀--help(一個非常龐大復雜的幫助文檔,官方用了410頁的篇幅PDF來介紹,如果我只言片語,你信我自己都不信。。)
用法: awk [POSIX 或 GNU 風格選項] -f 腳本文件 [--] 文件 ...
用法: awk [POSIX 或 GNU 風格選項] [--] '程序' 文件 ...
POSIX 選項: GNU 長選項:
-f 腳本文件 --file=腳本文件
-F fs --field-separator=fs
指定輸入文本分隔符,fs是一個字符串或者是一個正則表達式,
-v var=val --assign=var=val
將外部變量值付給var
-m[fr] val
-O --optimize
啟用一些優(yōu)化程序的內(nèi)部表示。
-W compat --compat
在兼容模式下運行awk。所以gawk的行為和標準的awk完全一樣,所有的awk擴展都被忽略。
-W copyleft --copyleft
打印簡短的版權(quán)信息
-W copyright --copyright
打印短版的通用公共許可證,然后退出
-W dump-variables[=file] --dump-variables[=file]
打印全局變量,其類型,提交的最終值的排序列表。
-W exec=file --exec=file
與-f類似,但與他有兩點不同,(我回頭把相關(guān)文檔上傳,太長)
-W gen-po --gen-po
(內(nèi)容太多)
-W help --help 打印幫助
-W lint[=fatal] --lint[=fatal]
警告可疑或不移植到其他的awk實現(xiàn)的結(jié)構(gòu)
-W lint-old --lint-old
打印關(guān)于不能向傳統(tǒng)unix平臺移植的結(jié)構(gòu)的警告
-W non-decimal-data --non-decimal-data
啟用自動輸入數(shù)據(jù)的解釋,八進制和十六進制值
-W profile[=file] --profile[=file]
啟用awk程序剖析
-W posix --posix
在嚴格意義上的POSIX模式運作。
-W re-interval --re-interval
允許間隔表達式在正則表達式上
-W source=program-text --source=program-text
-W traditional --traditional
傳統(tǒng)的Unix awk的正則表達式匹配
-W usage --usage
-W use-lc-numeric --use-lc-numeric
解析數(shù)字輸入時,強制使用的語言環(huán)境中的小數(shù)點字符
數(shù)據(jù)
-W version --version
提交錯誤報告請參考“gawk.info”中的“Bugs”頁,它位于打印版本中的“Reporting
Problems and Bugs”一節(jié)
注意:gawk是awk的GNU版本,即使help ,在ubuntu下也需要先安裝gawk
這回我們就不解讀了,為了增加大家的信息和樂趣,先來點基本的:
部分特殊變量:
NR: 表示記錄數(shù)量,在執(zhí)行過程中對應于行號
NF:表示字段數(shù)量,在執(zhí)行過程中對應于當前行的字段數(shù)
$0: 這個變量包含執(zhí)行過程中當前行的文本內(nèi)容
$1: 第一個字段的文本內(nèi)容
$2: 第二個字段的文本內(nèi)容
例子:
例1.
echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7"|\#這個\是在窗口中寫多行命令用的
awk '{
print "Line no:"NR",No of fields:"NF, "$0="$0,"$1="$1,"$2="$2,"$3="$3
}'
小注一下:$1是打印第一個,$NF打印最后一個字段,$(NF-1)打印倒數(shù)第二個
例2.
seq 5 | awk 'BEGIN{ sum=0;print "Summation:"}{print $1"+";sum+=1}END{print "==";print sum}'
這個例子用到了基本格式。
BEGIN中 初始化了sum,打印Summation
中間模塊打印了第一列,然后給sum+1
END中打印了sum
例3. 關(guān)于-v 外部變量
$ VAR=10000
$echo | awk –v VARIABLE=$VAR'{print VARABLE}'
還有另一種靈活的方法可以將多個外部變量傳遞給awk,例如:
$var1="value1" var2="value2"
$echo | awk '{print v1,v2}' v1=$var1 v2=$var2
如果來自文件
awk '{print v1,v2}' v1=$var1 v2=$var2 filename
例4
$awk 'NR < 5' #行號小于5
$awk 'NR==1,NR==4' #行號在1到5之間的行
$awk '/linux/' #包含樣式linux的行(可以用正則表達式指定樣式)
$awk '!/linux/' #不包含樣式linux的行
這次先寫這些,爭取在花2個篇幅能把awk做個比較全面的認識。
awk補充
之前我們學習了awk基本入門,我驚喜的發(fā)現(xiàn)有awk一篇詳細文章,有寫念頭,不能全部轉(zhuǎn)載,轉(zhuǎn)化成自己的方式來寫一些。
主講內(nèi)置變量和部分字符串函數(shù)
內(nèi)置變量(有翻譯特殊變量和環(huán)境變量,按照官方翻譯為內(nèi)置變量)
變量 |
說明 |
$n | 當前記錄的第n個字段,字段間由FS分隔。 |
$0 | 完整的輸入記錄。 |
ARGC | 命令行參數(shù)的數(shù)目。 |
ARGIND | 命令行中當前文件的位置(從0開始算)。 |
ARGV | 包含命令行參數(shù)的數(shù)組。 |
BINMODE | 在非POSIX系統(tǒng)上,這個變量指定的所有I / O使用二進制模式 |
CONVFMT | 數(shù)字轉(zhuǎn)換格式(默認值為%.6g) |
ENVIRON | 環(huán)境變量關(guān)聯(lián)數(shù)組。 |
ERRNO | 最后一個系統(tǒng)錯誤的描述。 |
FIELDWIDTHS | 字段寬度列表(用空格鍵分隔)。 |
FILENAME | 當前文件名。 |
FNR | 同NR,但相對于當前文件 |
FPAT |
這是一個正則表達式(字符串),告訴gawk基于匹配正則表達式的文本來創(chuàng)建字段 |
FS | 字段分隔符(默認是任何空格)。 |
IGNORECASE | 如果為真,則進行忽略大小寫的匹配。 |
LINT |
當這個變量為真(非零或非空),gawk的行為猶如"--lint"命令行選項 |
NF | 當前記錄中的字段數(shù)。 |
NR | 當前記錄數(shù)。 |
OFMT | 數(shù)字的輸出格式(默認值是%.6g)。 |
OFS | 輸出字段分隔符(默認值是一個空格)。 |
ORS | 輸出記錄分隔符(默認值是一個換行符)。 |
PROCINFO |
這個數(shù)組的元素提供訪問運行awk程序的信息 |
RLENGTH | 由match函數(shù)所匹配的字符串的長度。 |
RS | 記錄分隔符(默認是一個換行符)。 |
RT | 每次一條記錄被讀取的設置 |
RSTART | 由match函數(shù)所匹配的字符串的第一個位置。 |
SUBSEP |
數(shù)組下標分隔符(默認值是\034)。 |
TEXTDOMAIN | 此變量用于程序的國際化 |
藍色為新增加的內(nèi)置變量。
簡單舉例:
1.
01.sed 1q /etc/passwd | awk '{ FS = ":"; print $1 }'
打印密碼第一行,用冒號分隔符
2.
awk 'END{print FILENAME}' awk.txt
打印文本FILENAME
3. seq 100 | awk 'NR==4,NR==6'
打印4到6行
再介紹幾個awk內(nèi)置的字符串函數(shù),也講一部分。
length(string):
返回字符串的長度
index(string,serch_string):
返回search_string在字符串中出現(xiàn)的位置
split(string,array,delimiter):
用定界符生成一個字符串列表,并將該列表存入數(shù)組
substr(string,array,delimiter):
在字符串中用字符起止便宜量生成子串,并返回該子串
sub(regex,replacement_str,string):
將正則表達式匹配到的第一處內(nèi)容替換成replacement_str
gsub(regex,replacement_str,string):
和sub()類似。不過該函數(shù)會替換正則表達式匹配到的所有內(nèi)容
match(regex,string):
檢查正則表達式是否能夠匹配字符串。如果能夠匹配,返回非0值;否則,返回0.match()有兩個相關(guān)的特殊變量,分別是RSTART喝RLENGTH。變量RSTART包含正則表達式所匹配內(nèi)容的其實位置,而變量RLENGTH包含正則表達式所匹配內(nèi)容的長度。
舉例:
1.$ awk '{ sub(/test/, "mytest"); print }' testfile
在整個記錄中匹配,替換只發(fā)生在第一次匹配發(fā)生的時候
2.$ awk '{ sub(/test/, "mytest"); $1}; print }' testfile
在整個記錄的第一個域中進行匹配,替換只發(fā)生在第一次匹配發(fā)生的時候
3.$ awk '{ print index("test", "mytest") }' testfile
實例返回test在mytest的位置,結(jié)果應該是3
4.$ awk '{ print length( "test" ) }'
實例返回test字符串的長度。
awk補充二
這節(jié)可能要寫的比較粗了,時間太少。
一. 內(nèi)置函數(shù)
注意一種約定俗稱語法習慣: [a]代表a可選.
數(shù)字函數(shù)(Numeric Functions)
函數(shù)名 |
說明 |
atan2(y,x) | 返回y/x弧的反正切 |
cos(x) | 返回x的余弦 |
exp(x) | 返回x的指數(shù) |
int(x) | 返回最靠近的整數(shù),風向標指向0 |
log(x) | 返回x的自然對數(shù) |
rand() | 返回隨機數(shù) |
sin(x) | 返回x的正弦 |
sqrt(x) | 返回x的正平方根 |
srand([x]) | 生成隨機數(shù),可以設置起點 |
字符串操作函數(shù)(String-Manipulation Functions)
注意:藍色部分為gawk特有,awk沒有此函數(shù)功能。
函數(shù)名 |
說明 |
asort(source [, dest [, how ] ]) | 返回數(shù)組元素數(shù)(內(nèi)容較多) |
asorti(source [, dest [, how ] ]) | 同asort,(有細微差別) |
gensub(regexp, replacement, how [, target]) | 搜索正則表達式RegExp匹配的regexp |
gsub(regexp, replacement [, target]) | 將正則表達式匹配的第一處內(nèi)容替換成replacement_str |
index(in, find) | 返回find在字符串in中出現(xiàn)的位置 |
length([string]) | string 中的字符數(shù) |
match(string, regexp [, array]) | 檢查正則表達式能否匹配字符串 |
patsplit(string, array [, fieldpat [, seps ] ]) |
劃分件到由fieldpat定義的字符串,并存儲在array里,分隔字符串存在在seps數(shù)組 |
split(string, array [, fieldsep [, seps ] ]) | 用定界符生成一個字符串列表,并將該列表存入數(shù)組 |
sprintf(format, expression1, ...) | 打印 |
strtonum(str) | 字符轉(zhuǎn)轉(zhuǎn)換成數(shù)字 |
sub(regexp, replacement [, target]) | 將正則表達式匹配到的第一處內(nèi)容替換成replacement |
substr(string, start [, length]) | 分割字符串,根據(jù)其實位置和長度 |
tolower(string) | 轉(zhuǎn)換成小寫 |
toupper(string) | 轉(zhuǎn)換成大寫 |
輸入輸出函數(shù)(Input/Output Functions)
函數(shù) |
說明 |
close(filename [, how]) | 關(guān)閉文件輸入輸出流 |
fflush([filename]) | 刷新與文件名相關(guān)的任何緩沖輸出 |
system(command) | 執(zhí)行操作系統(tǒng)命令,返回值給awk程序 |
時間函數(shù)(Time Functions)
函數(shù) |
說明 |
mktime(datespec) | datespec為時間戳格式,與systime()格式一樣 |
strftime([format [, timestamp [, utc-flag]]]) | 格式化timestamp的內(nèi)容,返回日期格式 |
systime() | 返回系統(tǒng)時間,精確到秒 |
位操作函數(shù)(Bit-Manipulation Functions)
函數(shù) |
說明 |
and(v1, v2) | v1,v2的與操作結(jié)果 |
compl(val) | val的反碼 |
lshift(val, count) | 返回val左移count位的值 |
or(v1, v2) | v1,v2的或操作 |
rshift(val, count) | 返回val右移count位的值 |
xor(v1, v2) | 返回v1,v2的異或的值 |
獲取類型信息(Getting Type Information)
函數(shù) |
說明 |
isarray(x) | 如果x是數(shù)組,返回true.否則false |
字符串轉(zhuǎn)換函數(shù)(String-Translation Functions)
函數(shù) |
說明 |
bindtextdomain(directory [, domain]) | 設置awk要搜尋信息的目錄和域 |
dcgettext(string [, domain [, category]]) | 返回的字符串string 翻譯文本域domain 的語言環(huán)境類別category |
dcngettext(string1, string2, number [, domain [, category]]) |
返回string1和string2的翻譯數(shù)量的復數(shù)形式,string1,string2在語言環(huán)境類別的文本域里 |
內(nèi)置函數(shù)還有些高級特性,等許多實例,以后有機會補充。
二. 自定義函數(shù)
格式入下:
function name([parameter-list])
{
body-of-function
}
如:
function myprint(num)
{
printf "%6.3g\n", num
}
awk這個命令還有很多功能,打算就只寫這么多了。以后可能更多在一些例子里,與其他命令結(jié)合時會提到。
相關(guān)文章
shell 創(chuàng)建子進程及并行延時執(zhí)行命令方法
本文主要介紹了shell 創(chuàng)建子進程及并行延時執(zhí)行命令方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-01-01Linux下Tomcat啟動正常,但瀏覽器無法訪問的解決方法
下面小編就為大家?guī)硪黄狶inux下Tomcat啟動正常,但瀏覽器無法訪問的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02Linux環(huán)境下tcpdump網(wǎng)絡協(xié)議抓包與解析
這篇文章主要為大家介紹了Linux環(huán)境下tcpdump網(wǎng)絡協(xié)議抓包與解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09