色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux Awk用法總結(jié)

馬哥Linux運維 ? 來源:未知 ? 作者:胡薇 ? 2018-04-13 09:27 ? 次閱讀

Awk、sed與grep,俗稱Linux下的三劍客,它們之間有很多相似點,但是同樣也各有各的特色,相似的地方是它們都可以匹配文本,其中sed和awk還可以用于文本編輯,而grep則不具備這個功用。sed是一種非交互式且面向字符流的編輯器(a "non-interactive" stream-oriented editor),而awk則是一門模式匹配的編程語言,因為它的主要功能是用于匹配文本并處理,同時它有一些編程語言才有的語法,例如函數(shù)、分支循環(huán)語句、變量等等,當(dāng)然比起我們常見的編程語言,Awk相對比較簡單。

使用Awk,我們可以做以下事情:

將文本文件視為由字段和記錄組成的文本數(shù)據(jù)庫;

在操作文本數(shù)據(jù)庫的過程中能夠使用變量;

能夠使用數(shù)學(xué)運算和字符串操作

能夠使用常見的編程結(jié)構(gòu),例如條件分支與循環(huán);

能夠格式化輸出;

能夠自定義函數(shù);

能夠在awk腳本中執(zhí)行UNIX命令;

能夠處理UNIX命令的輸出結(jié)果;

裝備以上功能,awk能夠做得事情非常多。但千里之行,始于足下,我們首先從最基本的命令行語法開始,一步一步得走入awk的編程世界。

命令行語法

同sed一樣,awk的命令行語法也有兩種形式:

awk [-F ERE] [-v assignment] ... program [argument ...]awk [-F ERE] -f progfile ... [-v assignment] ...[argument ...]

這里的program類似sed中的script,因為我們一直強調(diào)awk是一門編程語言,所以將awk的腳本視為一段代碼。而awk的腳本同樣可以寫到一個文件中,并通過-f參數(shù)指定,這一點和sed是一樣的。program一般多個pattern和action序列組成,當(dāng)讀入的記錄匹配pattern時,才會執(zhí)行相應(yīng)的action命令。這里有一點要注意,在第一種形式中,除去命令行選項外,program參數(shù)一定要位于第一個位置。

Awk的輸入被解析成多個記錄(Record),默認(rèn)情況下,記錄的分隔符是 ,因此可以認(rèn)為一行就是一個記錄,記錄的分隔符可以通過內(nèi)置變量RS更改。當(dāng)記錄匹配某個pattern時,才會執(zhí)行后續(xù)的action命令。

而每個記錄由進一步地被分隔成多個字段(Field),默認(rèn)情況下字段的分隔符是空白符,例如空格、制表符等等,也可以通過-F ERE選項或者內(nèi)置變量FS更改。在awk中,可以通過$1,$2...來訪問對應(yīng)位置的字段,同時$0存放整個記錄,這一點有點類似shell下的命令行位置參數(shù)。關(guān)于這些內(nèi)容,我們會在下面詳細介紹,這里你只要知道有這些東西就好。

標(biāo)準(zhǔn)的awk命令行參數(shù)主要由以下三個:

-F ERE:定義字段分隔符,該選項的值可以是擴展的正則表達式(ERE);

-f progfile:指定awk腳本,可以同時指定多個腳本,它們會按照在命令行中出現(xiàn)的順序連接在一起;

-v assignment:定義awk變量,形式同awk中的變量賦值,即name=value,賦值發(fā)生在awk處理文本之前;

為了便于理解,這里舉幾個簡單的例子。通過-F參數(shù)設(shè)置冒號:為分隔符,并打印各個字段:

[kodango@devops ~]$ echo "1:2:3" | awk -F: '{print $1 " and " $2 " and " $3}'1 and 2 and 3

在awk的腳本中訪問通過-v選項設(shè)置的變量:

[kodango@devops ~]$ echo | awk -v a=1 'BEGIN {print a}'1

從上面可以看到,通過-v選項設(shè)置的變量在BEGIN的位置就可以訪問了。BEGIN是一個特殊的pattern,它在awk處理輸入之前就會執(zhí)行,可以認(rèn)為是一個初始化語句,與此對應(yīng)的還有END。

好像還沒介紹如何指定處理的文件,是不是最后的argument就是指定的文件?在看我這本書之前,我也是這樣認(rèn)為的,但是實際上arguemnt有兩種形式,它們分別是輸入文件(file)和變量賦值(assignment)。

awk可以同時指定多個輸入文件,如果輸入文件的文件名為'-',表示從標(biāo)準(zhǔn)輸入讀取內(nèi)容。

變量賦值類似-v選項,它的形式為name=value。awk中的變量名同一般的編程語言無太多區(qū)別,但是不能同awk的保留關(guān)鍵字重名,可以查看awk的man手冊查詢哪些是保留關(guān)鍵字。而變量值只有兩種形式:字符串和數(shù)值。變量賦值必須位于腳本參數(shù)的后面,與文件名參數(shù)無先后順序的要求,但是位于不同位置的賦值它的執(zhí)行時機是不同的。

我們用實際的例子來解釋這個區(qū)別,假設(shè)有兩個文件:a和b,它們的內(nèi)容分別如下所示:

[kodango@devops awk_temp]$ cat afile a[kodango@devops awk_temp]$ cat bfile b

為了說明賦值操作發(fā)生的時機,我們在BEGIN,正常處理,END三個地方都打印變量的值。

第一種情況: 變量賦值位于所有文件名參數(shù)之前

[kodango@devops awk_temp]$ awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' var=1 aBEGIN: PROCESS: 1END: 1

結(jié)果:賦值操作發(fā)生在正常處理之前,BEGIN動作之后。

第二種情況:變量賦值位于所有文件名之后:

[kodango@devops awk_temp]$ awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' a var=1 BEGIN: PROCESS: END: 1

結(jié)果:賦值操作發(fā)生在正常處理之后,END動作之前。

第三種情況:變量賦值位于文件名之間:

[kodango@devops awk_temp]$ awk 'BEGIN {print "BEGIN: " var} {print "PROCESS: " var} END {print "END: " var }' a var=1 bBEGIN: PROCESS: PROCESS: 1END: 1

結(jié)果:賦值操作發(fā)生在處理前面的文件之后,并且位于處理后面的文件之前;

總結(jié)如下:

如果變量賦值在第一個文件參數(shù)之前,在BEGIN動作之后執(zhí)行,影響到正常處理和END動作;

如果變量賦值在最后一個文件參數(shù)之后,在END動作之前執(zhí)行,僅影響END動作;

如果文件參數(shù)不存在,情況同1所述;

如果變量賦值位于多個文件參數(shù)之間,在變量賦值前面的文件被處理后執(zhí)行,影響到后續(xù)文件的處理和END動作;

所以變量賦值一定要考慮清楚用途,否則比較容易出錯,不過一般情況下也不會用到變量賦值。

自然地大家會將變量賦值與-v assignment選項進行比較,賦值的形式是一致的,但是-v選項的執(zhí)行時機比變量賦值要早:

[kodango@devops awk_temp]$ echo 1 | awk -v var=a 'BEGIN {print "BEGIN: " var}'BEGIN: a

可見,-v選項的賦值操作在BEGIN動作之前就執(zhí)行了。

變量賦值一定要小心不要與保留關(guān)鍵字重名,否則會報錯:

[kodango@devops awk_temp]$ echo 1 | awk -v BEGIN=1 'BEGIN {print "BEGIN: " BEGIN}'awk: fatal: cannot use gawk builtin `BEGIN' as variable name

記錄(Record)與字段(Field)

對于數(shù)據(jù)庫來說,一個數(shù)據(jù)庫表是由多條記錄組成的,每一行表示一條記錄(Record)。每條記錄由多列組成,每一列表示一個字段(Field)。Awk將一個文本文件視為一個文本數(shù)據(jù)庫,因此它也有記錄和字段的概念。默認(rèn)情況下,記錄的分隔符是回車,字段的分隔符是空白符,所以文本文件的每一行表示一個記錄,而每一行中的內(nèi)容被空白分隔成多個字段。利用字段和記錄,awk就可以非常靈活地處理文件的內(nèi)容。

可以通過-F選項來修改默認(rèn)的字段分隔符,例如/etc/passwd的每一行都是由冒號分隔成多個字段的,所以這里就需要將分隔符設(shè)置成冒號:

[kodango@devops awk_temp]$ awk -F: '{print $1}' /etc/passwd | head -3rootbindaemon

這里通過$1引用第一人字段,類似地$2表示第二個字段,$3表示第三個字段.... $0則表示整個記錄。內(nèi)置變量NF記錄著字段的個數(shù),所以$NF表示最后一個字段:

[kodango@devops awk_temp]$ awk -F: '{print $NF}' /etc/passwd | head -3/bin/bash/bin/false/bin/false

當(dāng)然,$(NF-1)表示倒數(shù)第二個。

內(nèi)置變量FS也可以用于更改字段分隔符,它記錄著當(dāng)前的字段分隔符:

[kodango@devops awk_temp]$ awk -F: '{print FS}' /etc/passwd | head -1:[kodango@devops awk_temp]$ awk -v FS=: '{print $1}' /etc/passwd | head -1root

記錄的分隔符可以通過內(nèi)置變量RS更改:

[kodango@devops awk_temp]$ awk -v RS=: '{print $0}' /etc/passwd | head -1root

如果將RS設(shè)置成空,行為有就一點怪異了,它會將連續(xù)不為空行的所有行(一個段落)當(dāng)作一個記錄,而且強制回車為字段分隔符:

[kodango@devops awk_temp]$ cat awk_man.txt The awk utility shall execute programs written in the awk programming language,which is specialized for textual data manipulation. An awk program is a sequenceof patterns and corresponding actions. When input is read that matches apattern, the action associated with that pattern is carried out.Input shall be interpreted as a sequence of records. By default, a record is a line,less its terminating , but this can be changed by using the RS built-invariable. Each record of input shall be matched in turn against each pattern in theprogram. For each pattern matched, the associated action shall be executed.[kodango@devops awk_temp]$ awk 'BEGIN {RS="";FS=":"} {print "First line: " $1}' awk_man.txt First line: The awk utility shall execute programs written in the awk programming language,First line: Input shall be interpreted as a sequence of records. By default, a record is a line,

這里,我們將變量賦值放到BEGIN動作中執(zhí)行,因為BEGIN動作是在文件處理之前執(zhí)行的,專門用于放初始化的語句。FS的賦值在這里是無效的,awk依然使用回車符來分隔字段。

腳本(Script)組成

命令行中的program部分,可以稱為awk代碼,也可以稱為awk腳本。一段awk腳本是由多個'pattern { action }'序列組成的。action是一個或者多個語句,它在輸入行匹配pattern的時候被執(zhí)行。如果pattern為空,表明這個action會在每一行處理時都會被執(zhí)行。下面的例子簡單地打印文件的每一行,這里不帶任何參數(shù)的print語句打印的是整個記錄,類似'print $0':

[kodango@devops awk_temp]$ echo -e 'line1 line2' | awk '{print}' line1line2

除了pattern { action },還可以在腳本中定義自定義的函數(shù),函數(shù)定義格式如下所示:

function name(parameter list) { statements }

函數(shù)的參數(shù)列表用逗號分隔,參數(shù)默認(rèn)是局部變量,無法在函數(shù)之外訪問,而在函數(shù)中定義的變量為全局變量,可以在函數(shù)之外訪問,如:

[kodango@devops awk_temp]$ echo line1 | awk 'function t(a) { b=a; print a;} { print b; t("kodango.me"); print b;}'kodango.mekodango.me

Awk腳本中的語句使用空行或者分號分隔,使用分號可以放在同一行,不過有時候會影響可讀性,尤其是分支或循環(huán)結(jié)構(gòu)中,很容易出錯。

如果Awk中的一個語句太長,要分成多行,可以在行為使用反斜杠'':

[kodango@devops awk_temp]$ cat test.awk function t(a){ b=a print "This is a very long line, so use backslash to escape the newline hen we will print the variable a: a=" a} { print b; t("kodango.me"); print b;}[kodango@devops awk_temp]$ echo 1 | awk -f test.awk This is a very long line, so use backslash to escape the newline then we will print the variable a: a=kodango.mekodango.me

這里我們將腳本寫到文件中,并通過-f參數(shù)來指定。但是,在一些特殊符號之后,是可以直接換行的,例如", { && ||"。

模式(Pattern)

模式是awk中比較重要的一部分,它有以下幾種情況:

/regular expression/: 擴展的正則表達式(Extended Regular Expression), 關(guān)于ERE可以參考這篇文章;

relational expression: 關(guān)系表達式,例如大于、小于、等于,關(guān)系表達式結(jié)果為true表示匹配;

BEGIN: 特殊的模式,在第一個記錄處理之前被執(zhí)行,常用于初始化語句的執(zhí)行;

END: 特殊的模式,在最后一個記錄處理之前被執(zhí)行,常用于輸出匯總信息

pattern, pattern:模式對,匹配兩者之間的所有記錄,類似sed的地址對;

例如查找匹配數(shù)字3的行:

[kodango@devops awk_temp]$ seq 1 20 | awk '/3/ {print}'313

相反地,可以在在正則表達式之前加上'!'表示不匹配:

[kodango@devops awk_temp]$ seq 1 5 | awk '!/3/ {print}'1245

除了BEGIN和END這兩個特殊的模式外,其余的模式都可以使用'&&'或者'||'運算符組合,前者表示邏輯與,后者表示邏輯或:

[kodango@devops awk_temp]$ seq 1 50 | awk '/3/ && /1/ {print}'1331

前面的正則都是整行匹配,有時候僅僅需要匹配某個字符,這樣我們可以用表達式$n ~ /ere/:

[kodango@devops ~]$ awk '$1 ~ /ko/ {print}' /etc/passwdkodango:x:1000:1000::/home/kodango:/bin/bash

有時候我們只想顯示特定和行,例如顯示第一行:

[kodango@devops ~]$ seq 1 5 | awk 'NR==1 {print}'1

正則表達式(Regular Expression)

和sed篇一樣,這里我不會詳細介紹正則表達式。因為正則表達式的內(nèi)容介紹起來太麻煩,還是推薦同學(xué)閱讀現(xiàn)有的文章(如Linux/Unix工具與正則表達式的POSIX規(guī)范),里面對各個流派的正則表達式歸納地很清楚了。

表達式(Expressions)

表達式可以由常量、變量、運算符和函數(shù)組成,常數(shù)和變量的值可以為字符串和數(shù)值。

Awk中的變量有三種類型:用戶定義的變量,內(nèi)置變量和字段變量。其中,內(nèi)置變量名都是大寫的。

變量并不非一定要被聲明或者被初始化,一個變量默認(rèn)的值是空字符串,只是在某些上下文上會隱式的自動轉(zhuǎn)換成數(shù)字0(例如數(shù)學(xué)運算),記住awk中的變量是無類型的,不存在字符串變量還是數(shù)字變量的區(qū)別,只是有時候為了解說方便,才會這么說。(感謝網(wǎng)友@紫云妃的提醒)

字段變量可以用$n來引用,n的取值范圍為[0,NF]。n可以為一個變量,例如$NF代碼最后一個字段,而$(NF-1)表示倒數(shù)第二個字段。

數(shù)組

數(shù)組是一種特殊的變量,awk中的數(shù)組都是關(guān)聯(lián)數(shù)組,它的下標(biāo)都是字符串值(man手冊中的原話是:All arrays in AWK are associative, i.e. indexed by string values),即使你使用的下標(biāo)是一個數(shù)字,awk也會將下標(biāo)隱式轉(zhuǎn)換成字符串。所以容易給人一個誤解,數(shù)組的下標(biāo)可以是數(shù)字或者字符串。

數(shù)組的賦值很簡單,下面將value賦值給數(shù)組下標(biāo)為index的元素:

array[index]=value

可以用for..in..語法遍歷數(shù)組元素,其中item是數(shù)組元素對應(yīng)的下標(biāo):

for (item in array)

當(dāng)然也可以在if分支判斷中使用in操作符:

if (item in array)

一個完整的例子如下所示:

[kodango@devops ~]$ echo "1 2 3" | awk '{for (i=0;i

內(nèi)置變量

Awk在內(nèi)部維護了許多內(nèi)置變量,或者稱為系統(tǒng)變量,例如之前提到的FS、RS等等。常見的內(nèi)置變量如下表所示

變量名

描述

ARGC 命令行參數(shù)的各個,即ARGV數(shù)組的長度
ARGV 存放命令行參數(shù)
CONVFMT 定義awk內(nèi)部數(shù)值轉(zhuǎn)換成字符串的格式,默認(rèn)值為"%.6g"
OFMT 定義輸出時數(shù)值轉(zhuǎn)換成字符串的格式,默認(rèn)值為"%.6g"
ENVIRON 存放系統(tǒng)環(huán)境變量的關(guān)聯(lián)數(shù)組
FILENAME 當(dāng)前被處理的文件名
NR 記錄的總個數(shù)
FNR 當(dāng)前文件中的記錄的總個數(shù)
FS 字段分隔符,默認(rèn)為空白
NF 每個記錄中字段的個數(shù)
RS 記錄的分隔符,默認(rèn)為回車
OFS 輸出時字段的分隔符,默認(rèn)為空白
ORS 輸出時記錄的分隔符,默認(rèn)為回車
RLENGTH 被match函數(shù)匹配的子串長度
RSTART 被match函數(shù)匹配的子串位于目標(biāo)字符串的起始下標(biāo)

下面主要介紹幾個比較難理解的內(nèi)置變量:

1.ARGV與ARGC

ARGV與ARGC的意思比較好理解,就像C語言main(int argc, char **argv)。ARGV數(shù)組的下標(biāo)從0開始到ARGC-1,它存放的是命令行參數(shù),并且排除命令行選項(例如-v/-f)以及program部分。因此事實上ARGV只是存儲argument的部分,即文件名(file)以及命令行變量賦值兩部分的內(nèi)容。

通過下面的例子可以大概了解ARGC與ARGV的用法:

[kodango@devops awk_temp]$ awk 'BEGIN {> for (i = 0; i < ARGC; i++)> print ARGV[i]> }' inventory-shipped BBS-listawkinventory-shippedBBS-list

ARGV的用法不僅限于此,它是可以修改的,可以更改數(shù)組元素的值,可以增加數(shù)組元素或者刪除數(shù)組元素。

a. 更改ARGV元素的值

假設(shè)我們有a, b兩個文件,它們各有一行內(nèi)容:file a和file b?,F(xiàn)在利用ARGV,我們可以做到偷梁換柱:

[kodango@devops awk_temp]$ awk 'BEGIN{ARGV[1]="b"} {print}' afile b

這里要注意ARGV[1]="b"的引號不能缺少,否則ARGV[1]=b會將變量b的值賦值給ARGV[1]。

當(dāng)awk處理完一個文件之后,它會從ARGV的下一個元素獲取參數(shù),如果是一個文件則繼續(xù)處理,如果是一個變量賦值則執(zhí)行賦值操作:

[kodango@devops awk_temp]$ awk 'BEGIN{ARGV[1]="var=1"} {print var}' a b1

為什么這里只打印一次變量值呢?可以回頭再看看上一篇中介紹變量賦值的內(nèi)容。

而當(dāng)下一個元素為空時,則跳過不處理,這樣可以避開處理某個文件:

[kodango@devops awk_temp]$ awk 'BEGIN{ARGV[1]=""} {print}' a bfile b

上面的例子中a這個文件就被跳過了。

而當(dāng)下一個元素的值為"-"時,表明從標(biāo)準(zhǔn)輸入讀取內(nèi)容:

[kodango@devops awk_temp]$ awk 'BEGIN{ARGV[1]="-"} {print}' a baa # --> 這里按下CTRL+D停止輸入file b

b. 刪除ARGV元素

刪除ARGV元素和將元素的值賦值為空的效果是一樣的,它們都會跳轉(zhuǎn)對某個參數(shù)的處理:

[kodango@devops awk_temp]$ awk 'BEGIN{delete ARGV[1]} {print}' a bfile b

刪除數(shù)組元素可以用delete語句。

c. 增加ARGV元素

我第一次看到ARGV變量的時候就在想,能不能利用ARGV變量避免提供命令行參數(shù),就像這樣:

awk 'BEGIN{ARGV[1]="a";} {print}'

但是事實上這樣不行,awk會依然從標(biāo)準(zhǔn)輸入中獲取內(nèi)容。下面的方法倒是可以,首先增加ARGC的值,再增加ARGV元素,我到現(xiàn)在也沒搞懂這兩者的區(qū)別:

[kodango@devops awk_temp]$ awk 'BEGIN{ARGC+=1;ARGV[1]="a"} {print}'file a

2.CONVFMT與OFMT

Awk中允許數(shù)值到字符串相互轉(zhuǎn)換,其中內(nèi)置變量CONVFMT定義了awk內(nèi)部數(shù)值到字符串轉(zhuǎn)換的格式,它的默認(rèn)值為"%.6g":

[kodango@devops awk_temp]$ awk 'BEGIN { printf "CONVFMT=%s, num=%f, str=%s ", CONVFMT, 12.11, 12.11}' CONVFMT=%.6g, num=12.110000, str=12.11

通過更改CONVFMT,我們可以定義自己的轉(zhuǎn)換格式:

[kodango@devops awk_temp]$ awk 'BEGIN { CONVFMT="%d"; printf "CONVFMT=%s, num=%f, str=%s ", CONVFMT, 12.11, 12.11 }' CONVFMT=%d, num=12.110000, str=12

與此對應(yīng)地還有一個內(nèi)置變量OFMT,它與CONVFMT的作用是類似的,只不過是影響輸出的時候數(shù)字轉(zhuǎn)換成字符串的格式:

[kodango@devops awk_temp]$ awk 'BEGIN { OFMT="%d";print 12.11 }' 12

3.ENVIRON

ENVIRON是一個存放系統(tǒng)環(huán)境變量的關(guān)聯(lián)數(shù)組,它的下標(biāo)是環(huán)境變量名稱,值是相應(yīng)環(huán)境變量的值。例如:

[kodango@devops awk_temp]$ awk 'BEGIN { print ENVIRON["USER"] }' kodango

利用環(huán)境變量也可以將值傳遞給awk:

[kodango@devops awk_temp]$ U=hello awk 'BEGIN { print ENVIRON["U"] }' hello

可以利用for..in循環(huán)遍歷ENVIRON數(shù)組:

[kodango@devops awk_temp]$ awk 'BEGIN { for (env in ENVIRON) printf "%s=%s ", env, ENVIRON[env]; }'

4.RLENGTH與RSTART

RLENGTH與RSTART都是與match函數(shù)相關(guān)的,前者表示匹配的子串長度,后者表示匹配的子串位于目標(biāo)字符串的起始下標(biāo)。例如:

[kodango@devops ~]$ awk 'BEGIN {match("hello,world", /llo/); print RSTART,RLENGTH}'3 3

關(guān)于match函數(shù),我們會在以后介紹。

運算符

表達式中必然少不了運算符,awk支持的運算符可以參見man手冊中的“Expressions in awk”一小節(jié)內(nèi)容:

[kodango@devops awk_temp]$ man awk | grep "^ *Table: Expressions in" -A 42 | sed 's/^ *//' Table: Expressions in Decreasing Precedence in awkSyntax Name Type of Result Associativity( expr ) Grouping Type of expr N/A$expr Field reference String N/A++ lvalue Pre-increment Numeric N/A-- lvalue Pre-decrement Numeric N/Alvalue ++ Post-increment Numeric N/Alvalue -- Post-decrement Numeric N/Aexpr ^ expr Exponentiation Numeric Right! expr Logical not Numeric N/A+ expr Unary plus Numeric N/A- expr Unary minus Numeric N/Aexpr * expr Multiplication Numeric Left...以下省略...

語句(Statement)

到目前為止,用得比較多的語句就是print,其它的還有printf、delete、break、continue、exit、next等等。這些語句與函數(shù)不同的是,它們不會使用帶括號的參數(shù),并且沒有返回值。不過也有意外,比如printf就可以像函數(shù)一樣的調(diào)用:

[kodango@devops awk_temp]$ echo 1 | awk '{printf("%s ", "abc")}'abc

break和continue語句,大家應(yīng)該比較了解,分別用于跳出循環(huán)和跳到下一個循環(huán)。

delete用于刪除數(shù)組中的某個元素,這個我們在上面介紹ARGV的時候也使用過。

exit的用法顧名思義,就是退出awk的處理,然后會執(zhí)行END部分的內(nèi)容:

[kodango@devops awk_temp]$ echo $'line1 line2' | awk '{print;exit} END {print "exit.."}' line1exit..

next語句類似sed的n命令,它會讀取下一條記錄,并重新回到腳本的最開始處執(zhí)行:

[kodango@devops awk_temp]$ echo $'line1 line2' | awk '{> print "Before next.."> print $0 > next> print "After next.."> }'Before next..line1Before next..line2

從上面可以看出next后面的print語句不會執(zhí)行。

print與printf語句是使用最多的,它們將內(nèi)容輸出到標(biāo)準(zhǔn)輸出。注意在print語句中,輸出的變量之間帶不帶逗號是有區(qū)別的:

[kodango@devops awk_temp]$ echo "1 2" | awk '{print $1, $2}'1 2[kodango@devops awk_temp]$ echo "1 2" | awk '{print $1 $2}'12

print輸出時,字段之間的分隔符可以由OFS重新定義:

[kodango@devops awk_temp]$ echo "1 2" | awk '{OFS=";";print $1,$2}'1;2

除此之外,print的輸出還可以重定向到某個文件中或者某個命令:

print items > output-fileprint items >> output-fileprint items | command

假設(shè)有這一樣一個文件,第一列是語句名稱,第二列是對應(yīng)的說明:

[kodango@devops awk_temp]$ cat column.txt statement|descriptiondelete|delete item from an arrayexit|exit from the awk processnext|read next input record and process

現(xiàn)在我們要將兩列的內(nèi)容分別輸出到statement.txt和description.txt兩個文件中:

[kodango@devops awk_temp]$ awk -F'|' '{> print $1 > "statement.txt";> print $2 > "description.txt"> }' column.txt [kodango@devops awk_temp]$ cat statement.txt statementdeleteexitnext[kodango@devops awk_temp]$ cat description.txt descriptiondelete item from an arrayexit from the awk processread next input record and process

下面是一個重定向到命令的例子,假設(shè)我們要對下面的文件進行排序:

[kodango@devops awk_temp]$ cat num.list 13295

可以通過將print的內(nèi)容重定向到"sort -n"命令:

[kodango@devops awk_temp]$ awk '{print | "sort -n"}' num.list 12359

printf命令的用法與print類似,也可以重定向到文件或者輸出,只不過printf比print多了格式化字符串的功能。printf的語法也大多數(shù)語言包括bash的printf命令類似,這里就不多介紹了。

awk的函數(shù)分成數(shù)學(xué)函數(shù)、字符串函數(shù)、I/O處理函數(shù)以及用戶自定義的函數(shù),其中用戶自定義的函數(shù)我們在上一篇中也有簡單的介紹,下面我們一一來介紹這幾類函數(shù)。

數(shù)學(xué)函數(shù)

awk中支持以下數(shù)學(xué)函數(shù):

atan2(y,x):反正切函數(shù);

cos(x):余弦函數(shù);

sin(x):正弦函數(shù);

exp(x):以自然對數(shù)e為底指數(shù)函數(shù);

log(x):計算以e 為底的對數(shù)值;

sqrt(x):絕對值函數(shù);

int(x):將數(shù)值轉(zhuǎn)換成整數(shù);

rand():返回0到1的一個隨機數(shù)值,不包含1;

srand([expr]):設(shè)置隨機種子,一般與rand函數(shù)配合使用,如果參數(shù)為空,默認(rèn)使用當(dāng)前時間為種子;

例如,我們使用rand()函數(shù)生成一個隨機數(shù)值:

[kodango@devops awk_temp]$ awk 'BEGIN {print rand(),rand();}'0.237788 0.291066[kodango@devops awk_temp]$ awk 'BEGIN {print rand(),rand();}'0.237788 0.291066

但是你會發(fā)現(xiàn),每次awk執(zhí)行都會生成同樣的隨機數(shù),但是在一次執(zhí)行過程中產(chǎn)生的隨機數(shù)又是不同的。因為每次awk執(zhí)行都使用了同樣的種子,所以我們可以用srand()函數(shù)來設(shè)置種子:

[kodango@devops awk_temp]$ awk 'BEGIN {srand();print rand(),rand();}'0.171625 0.00692412[kodango@devops awk_temp]$ awk 'BEGIN {srand();print rand(),rand();}'0.43269 0.782984

這樣每次生成的隨機數(shù)就不一樣了。

利用rand()函數(shù)我們也可以生成1到n的整數(shù):

[kodango@devops awk_temp]$ awk '> function randint(n) { return int(n*rand()); }> BEGIN { srand(); print randint(10);> }'3

字符串函數(shù)

awk中包含大多數(shù)常見的字符串操作函數(shù)。

1.sub(ere, repl[, in])

描述:簡單地說,就是將in中匹配ere的部分替換成repl,返回值是替換的次數(shù)。如果in參數(shù)省略,默認(rèn)使用$0。替換的動作會直接修改變量的值。

下面是一個簡單的替換的例子:

[kodango@devops ~]$ echo "hello, world" | awk '{print sub(/ello/, "i"); print}'1hi, world

在repl參數(shù)中&是一個元字符,它表示匹配的內(nèi)容,例如:

[kodango@devops ~]$ awk 'BEGIN {var="kodango"; sub(/kodango/, "hello, &", var); print var}'hello, kodango

2.gsub(ere, repl[, in])

描述:同sub()函數(shù)功能類似,只不過是gsub()是全局替換,即替換所有匹配的內(nèi)容。

3.index(s, t)

描述:返回字符串t在s中出現(xiàn)的位置,注意這里位置是從1開始計算的,如果沒有找到則返回0。

例如:

[kodango@devops ~]$ awk 'BEGIN {print index("kodango", "o")}'2[kodango@devops ~]$ awk 'BEGIN {print index("kodango", "w")}'0

4.length[([s])]

描述:返回字符串的長度,如果參數(shù)s沒有指定,則默認(rèn)使用$0作為參數(shù)。

例如:

[kodango@devops ~]$ awk 'BEGIN {print length('kodango');}'0[kodango@devops ~]$ echo "first line" | awk '{print length();}'10

5.match(s, ere)

描述: 返回字符串s匹配ere的起始位置,如果不匹配則返回0。該函數(shù)會定義RSTART和RLENGTH兩個內(nèi)置變量。RSTART與返回值相同,RLENGTH記錄匹配子串的長度,如果不匹配則為-1。

例如:

[kodango@devops ~]$ awk 'BEGIN {print match("kodango", /dango/);printf "Matched at: %d, Matched substr length: %d ", RSTART, RLENGTH;}'3Matched at: 3, Matched substr length: 5

6.split(s, a[, fs])

描述:將字符串按照分隔符fs,分隔成多個部分,并存到數(shù)組a中。注意,存放的位置是從第1個數(shù)組元素開始的。如果fs為空,則默認(rèn)使用FS分隔。函數(shù)返回值分隔的個數(shù)。

例如:

[kodango@devops ~]$ awk 'BEGIN {> split("1;2;3;4;5", arr, ";")> for (i in arr)> printf "arr[%d]=%d ", i, arr[i];> }'arr[4]=4arr[5]=5arr[1]=1arr[2]=2arr[3]=3

這里有一個奇怪的地方是for..in..輸出的數(shù)組不是按順序輸出的,如果要按順序輸出可以用常規(guī)的for循環(huán):

[kodango@devops ~]$ awk 'BEGIN {> split("1;2;3;4;5", arr, ";")> for (i=0;^C[kodango@devops ~]$ awk 'BEGIN {> n=split("1;2;3;4;5", arr, ";")> for (i=1; i<=n; i++)> printf "arr[%d]=%d ", i, arr[i];> }'arr[1]=1arr[2]=2arr[3]=3arr[4]=4arr[5]=5

7.sprintf(fmt, expr, expr, ...)

描述:類似printf,只不過不會將格式化后的內(nèi)容輸出到標(biāo)準(zhǔn)輸出,而是當(dāng)作返回值返回。

例如:

[kodango@devops ~]$ awk 'BEGIN {> var=sprintf("%s=%s", "name", "value")> print var> }'name=value

8.substr(s, m[, n])

描述:返回從位置m開始的,長度為n的子串,其中位置從1開始計算,如果未指定n或者n值大于剩余的字符個數(shù),則子串一直到字符串末尾為止。

例如:

[kodango@devops ~]$ awk 'BEGIN { print substr("kodango", 2, 3); }'oda[kodango@devops ~]$ awk 'BEGIN { print substr("kodango", 2); }'odango

9.tolower(s)

描述:將字符串轉(zhuǎn)換成小寫字符。

例如:

[kodango@devops ~]$ awk 'BEGIN {print tolower("KODANGO");}'kodango

10.toupper(s)

描述:將字符串轉(zhuǎn)換成大寫字符。

例如

[kodango@devops ~]$ awk 'BEGIN {print tolower("kodango");}'KODANGO

I/O處理函數(shù)

1.getline

getline的用法相對比較復(fù)雜,它有幾種不同的形式。不過它的主要作用就是從輸入中每次獲取一行輸入。

a.expression | getline [var]

這種形式將前面管道前命令輸出的結(jié)果作為getline的輸入,每次讀取一行。如果后面跟有var,則將讀取的內(nèi)容保存到var變量中,否則會重新設(shè)置$0和NF。

例如,我們將上面的statement.txt文件的內(nèi)容顯示作為getline的輸入:

[kodango@devops awk_temp]$ awk 'BEGIN { while("cat statement.txt" | getline var) print var}' statementdeleteexitnext

上面的例子中命令要用雙引號,"cat statement.txt",這一點同print/printf是一樣的。

如果不加var,則直接寫到$0中,注意NF值也會被更新:

[kodango@devops awk_temp]$ awk 'BEGIN { while("cat statement.txt" | getline) print $0,NF}' statement 1delete 1exit 1next 1

b.getline [var]

第二種形式是直接使用getline,它會從處理的文件中讀取輸入。同樣地,如果var沒有,則會設(shè)置$0,并且這時候會更新NF,NR和FNR:

[kodango@devops awk_temp]$ awk '{ > while (getline) > print NF, NR, FNR, $0;> }' statement.txt1 2 2 delete1 3 3 exit1 4 4 next

c.getline [var] < expression

第三種形式從expression中重定向輸入,與第一種方法類似,這里就不加贅述了。

2.close

close函數(shù)可以用于關(guān)閉已經(jīng)打開的文件或者管道,例如getline函數(shù)的第一種形式用到管道,我們可以用close函數(shù)把這個管道關(guān)閉,close函數(shù)的參數(shù)與管道的命令一致:

[kodango@devops awk_temp]$ awk 'BEGIN {while("cat statement.txt" | getline) { print $0; close("cat statement.txt");}}'statementstatementstatementstatementstatement

但是每次讀了一行后,關(guān)閉管道,然后重新打開又重新讀取第一行就死循環(huán)了。所以要慎用,一般情況下也很少會用到close函數(shù)。

3.system

這個函數(shù)很簡單,就是用于執(zhí)行外部命令,例如:

[kodango@devops awk_temp]$ awk 'BEGIN {system("uname -r");}'3.6.2-1-ARCH

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編程語言
    +關(guān)注

    關(guān)注

    10

    文章

    1942

    瀏覽量

    34707
  • SED
    SED
    +關(guān)注

    關(guān)注

    0

    文章

    25

    瀏覽量

    27085
  • grep
    +關(guān)注

    關(guān)注

    0

    文章

    22

    瀏覽量

    4723

原文標(biāo)題:Awk是什么?一文帶運維小白快速掌握Linux Awk用法

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux Awk命令實例教程

    Awk是一種通用腳本語言,用于高級文本處理的。它主要用作報告和分析工具。與大多數(shù)其他程序性編程語言不同。
    發(fā)表于 12-08 16:32 ?588次閱讀

    Linux中g(shù)rep、sed和awk命令詳解

    今天給大家聊一聊Linux中文本操作的`三劍客:awk、grep、sed`,因其功能強大、使用頻繁,且是Linux下文本處理的得力利器,常被稱之為`文本三劍客`。`grep`常用于查找,`sed`常用于取行和替換,而`
    發(fā)表于 04-26 17:20 ?3239次閱讀
    <b class='flag-5'>Linux</b>中g(shù)rep、sed和<b class='flag-5'>awk</b>命令詳解

    Linux中的Awk定義、用法詳解

    使用Awk,我們可以做以下事情:將文本文件視為由字段和記錄組成的文本數(shù)據(jù)庫;在操作文本數(shù)據(jù)庫的過程中能夠使用變量;能夠使用數(shù)學(xué)運算和字符串操作;能夠使用常見的編程結(jié)構(gòu),例如條件分支與循環(huán)。
    的頭像 發(fā)表于 12-11 16:26 ?6012次閱讀
    <b class='flag-5'>Linux</b>中的<b class='flag-5'>Awk</b>定義、<b class='flag-5'>用法</b>詳解

    linux awk命令簡單易懂分分鐘學(xué)會

    awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數(shù)據(jù)分析并生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認(rèn)分隔符將每行切片,切開的部分再進行各種分析處理。
    的頭像 發(fā)表于 03-17 10:15 ?4699次閱讀

    快速掌握AWK的基本使用方式

    本文大部分內(nèi)容翻譯自我開始學(xué)習(xí)AWK時看到的一篇英文文章 AWK Tutorial ,覺得對AWK入門非常有幫助,所以對其進行了粗略的翻譯,并對其中部分內(nèi)容進行了刪減或者補充,希望能為對AWK
    的頭像 發(fā)表于 08-20 14:17 ?2225次閱讀
    快速掌握<b class='flag-5'>AWK</b>的基本使用方式

    linuxawk以及重定向命令如何使用?

    awk語言的最基本功能是在文件或字符串中基于指定規(guī)則瀏覽和抽取信息,awk抽取信息后,才能進行其他文本操作,完整的awk腳本通常用來格式化文本文件中的信息
    發(fā)表于 10-18 17:25 ?3次下載

    總結(jié)Linux中用于文本處理的awk、sed、grep命令用法

    awk基礎(chǔ)概念Awk把文件(或其他方式的輸入流, 如重定向輸入)看作一個記錄集, 把每一行看作一條記錄, 把每一行中以空格(或\t,或用戶自己指定的分隔符)分割的字符串看作一個字
    發(fā)表于 04-02 14:32 ?316次閱讀

    干貨:Linux內(nèi)核中等待隊列的四個用法

    Linux內(nèi)核里的等待隊列機制在做驅(qū)動開發(fā)時用的非常多,多用來實現(xiàn)阻塞式訪問,下面簡單總結(jié)了等待隊列的四種用法,希望對讀者有所幫助。
    的頭像 發(fā)表于 06-20 09:59 ?2846次閱讀

    Linuxawk命令的格式和匹配模式

    1.命令簡介 AWK 是文本處理語言,是一個強大的文本分析工具,是 Unix/Linux 環(huán)境中功能強大的數(shù)據(jù)處理引擎之一。數(shù)據(jù)可以來自標(biāo)準(zhǔn)輸入(stdin)、一個或多個文件或其它命令的輸出。它支持
    的頭像 發(fā)表于 03-11 16:24 ?3938次閱讀

    Linux三劍客之awk實戰(zhàn)詳解教程

    awk 強大的功能,是一般 Linux 命令無法比擬的。在本文中,我不會告訴你 awk 也是一種編程語言,免得會嚇到你。我們只需把它當(dāng)做 Linux 下一款強大的文本分析工具即可。
    的頭像 發(fā)表于 03-31 17:12 ?2314次閱讀
    <b class='flag-5'>Linux</b>三劍客之<b class='flag-5'>awk</b>實戰(zhàn)詳解教程

    這些awk用法你會用幾個

    awk也是流式編輯器,針對文檔中的行來操作,一行一行地執(zhí)行。awk工具其實是很復(fù)雜的(有專門的書來介紹它的應(yīng)用),對于初學(xué)者來說,只要能處理日常管理工作中的問題即可。鑒于此,阿銘僅介紹比較常見的awk應(yīng)用,如果你感興趣再去深入研
    的頭像 發(fā)表于 12-05 09:32 ?590次閱讀

    Linux系統(tǒng)維護命令的用法

    Linux有很多命令,每個命令基本可以用一篇文章介紹,本文僅簡單總結(jié)一些常用系統(tǒng)維護命令的用法
    的頭像 發(fā)表于 04-17 14:57 ?1042次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)維護命令的<b class='flag-5'>用法</b>

    關(guān)于linuxawk高效命令集錦

    今天浩道跟大家分享關(guān)于linux三劍客之一的awk相關(guān)的高效命令集錦!
    發(fā)表于 04-20 10:09 ?339次閱讀

    總結(jié)linux命令行的主要用法

    Linux命令行是一種在Linux操作系統(tǒng)中通過文本界面來執(zhí)行指令和管理系統(tǒng)的方式。它提供了豐富的功能和靈活性,幫助用戶完成各種任務(wù)。本文將詳細介紹Linux命令行的主要用法,包括常見
    的頭像 發(fā)表于 11-17 10:19 ?662次閱讀

    AWK工具介紹

    awk是什么 awk是一個強大的linux命令,有強大的文本格式化的能力,好比將一些文本數(shù)據(jù)格式化成專業(yè)的excel表的樣式。 awk早期在Unix上實現(xiàn),我們用的
    的頭像 發(fā)表于 12-17 11:21 ?79次閱讀
    <b class='flag-5'>AWK</b>工具介紹
    主站蜘蛛池模板: 果冻传媒最新视频在线观看| 亚洲综合中文字幕无线码| 亚洲精品不卡在线| 小黄文污到你湿| 熟妇内谢69XXXXXA片| 美女脱得只剩皮肤| 婷婷午夜影院| 18禁三级黄| 又黄又爽又无遮挡在线观看免费| 暗卫受被肉到失禁各种PLAY| 精品久久免费观看| 色偷偷888欧美精品久久久| 永久免费看bbb| 国产精品线路一线路二| 国产午夜视频在永久在线观看| 久久夜色噜噜噜亚洲AV0000| 色偷偷7777www| a亚洲在线观看不卡高清| 99影视久久电影网久久看影院| 国产伊人自拍| 十八禁啪啦啪漫画| 亚洲国产AV精品卡一卡二| YELLOW视频在线观看最新 | 色99蜜臀AV无码| 最新国产在线视频| 国产综合在线视频| 色狠狠AV老熟女| caoporon超碰在线视频| 久久免费看少妇级毛片蜜臀| 午夜深情在线观看免费| 成人免费视频无遮挡在线看| 高挑人妻无奈张开腿| 男子扒开美女尿口做羞羞的事| 四虎影视国产精品亚洲精品| 把她带到密室调教性奴| 女人夜夜春| 99精品国产高清自在线看超| 伦理片在线3348| 最好看中文字幕国语| 浪荡受自我调教纯肉BL| 在线播放av欧美无码碰|