gawk程序
? ? 雖然sed編輯器是非常方便自動(dòng)修改文本文件的工具,但其也有自身的限制。通常你需要一個(gè)用來(lái)處理文件中的數(shù)據(jù)的更高級(jí)工具,他能提供一個(gè)類(lèi)編程環(huán)境來(lái)修改和重新組織文件中的數(shù)據(jù),這正是gawk能夠做到的。
? ? 說(shuō)明:在所有發(fā)行版中都沒(méi)有默認(rèn)安裝gawk程序。如果你所用的linux發(fā)行版中沒(méi)有包含gawk,請(qǐng)參考第9章中的內(nèi)容來(lái)安裝gawk包。
? ??gawk程序是unix中的原始程序的GNU版本。gawk程序讓流編輯邁上了一個(gè)新的臺(tái)階,它提供了一種編程語(yǔ)言而不只是編輯器命令。在gawk編程語(yǔ)言中,你可以做下面的事情:
定義變量來(lái)保存數(shù)據(jù):
定義變量來(lái)保存數(shù)據(jù);
使用算術(shù)和字符串操作符來(lái)處理數(shù)據(jù);
使用結(jié)構(gòu)化變成概念(比如if-then語(yǔ)句和循環(huán))來(lái)為數(shù)據(jù)處理增加處理邏輯;
通過(guò)提取數(shù)據(jù)文件中的數(shù)據(jù)元素,將其重新排列或格式化,生成格式化報(bào)告。
? ?gawk程序的報(bào)告生成能力通常用來(lái)從大文本文件中提取數(shù)據(jù)元素,他將格式化成可讀的報(bào)告。其中最完美的例子時(shí)格式化日志文件。在日志文件中找出錯(cuò)誤行會(huì)很難,gawk程序可以讓你從日志文件中過(guò)濾出需要的數(shù)據(jù)元素,然后你可以將其格式化,時(shí)的重要的數(shù)據(jù)更易于閱讀。
? ?1. gawk命令格式
? ? gawk程序的基本格式如下:
? ? gawk options program file?
? ?表19-2 顯示了gawk程序可用選項(xiàng)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 表19-2 gawk選項(xiàng)
選項(xiàng)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?描述
-F fs? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指定行中劃分?jǐn)?shù)據(jù)字段的字段分隔符
-f file? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 從指定的文件中讀取程序
-v var=value? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?定義gawk程序中的一個(gè)變量及默認(rèn)值
-mf? N? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?指定要處理的數(shù)據(jù)文件中的最大字段數(shù)
-mr N? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指定數(shù)據(jù)文件中的最大數(shù)據(jù)行數(shù)
-w keyword? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?指定gawk的兼容模式或者警告等級(jí)
命令行選項(xiàng)提供了一個(gè)簡(jiǎn)單的途徑來(lái)定制gawk程序的功能。我們會(huì)在探索gawk進(jìn)一步了解這些選項(xiàng)。
? ?gawk的強(qiáng)大之處在于程序腳本。可以寫(xiě)腳本來(lái)讀取文本行的數(shù)據(jù),然后處理并顯示數(shù)據(jù),創(chuàng)建任何類(lèi)型的輸出報(bào)告。
2 從命令行讀取程序腳本
? ?gawk程序腳本用一對(duì)花括號(hào)來(lái)定義。你必須將腳本命令放到兩個(gè)花括號(hào)({})中。如果你錯(cuò)誤地使用了圓括號(hào)來(lái)包含gawk腳本,就會(huì)得到類(lèi)似下面的錯(cuò)誤提示。
$ gawk '(print "Hello world!")'
gawk: cmd. line:1: (print "Hello world!")
gawk: cmd. line:1: ?^ syntax error
gawk: cmd. line:2: (print "Hello world!")
gawk: cmd. line:2: ? ? ? ? ? ? ? ? ? ? ? ^ unexpected newline or end of string
由于gawk命令行假定程序是單個(gè)文本字符串,你還必須將腳本放進(jìn)單引號(hào)中。下面的例子時(shí)在命令行中指定了一個(gè)簡(jiǎn)單的gawk程序腳本:
gawk '{print "Hello world!"}'
這個(gè)程序腳本定義了一個(gè)命令:print命令。這個(gè)命令名副其實(shí):它會(huì)將文本打印到STDOUT。如果嘗試運(yùn)行這個(gè)命令,你可能會(huì)有些失望,因?yàn)槭裁匆膊粫?huì)發(fā)生。原因在于沒(méi)有任何在命令行指定的文件名,所以gawk程序會(huì)從STDIN接收數(shù)據(jù)。在運(yùn)行這個(gè)程序時(shí),它會(huì)一直等待從STDIN輸入的文本。
? ? 如果你輸入一行文本并按下回車(chē)鍵,gawk會(huì)對(duì)這行文本運(yùn)行一遍程序腳本。跟sed編輯器一樣,gawk程序會(huì)針對(duì)數(shù)據(jù)流中的每行文本執(zhí)行程序腳本。由于程序腳本被設(shè)為顯示一行固定的文本字符串,因此不管你在數(shù)據(jù)流中輸入什么文本,都會(huì)得到同樣的文本輸出。
gawk '{print "Hello World!"}'
This is a test
Hello world
hello
Hello world
This is a another test
Hello world
要終止這個(gè)gawk程序,你必須表名數(shù)據(jù)流結(jié)束了。bash shell提供了一個(gè)組合鍵來(lái)生成EOF(End-of-line)字符。 Ctrl+D組合鍵會(huì)在bash中產(chǎn)生一個(gè)EOF字符。這個(gè)組合鍵能夠終止該gawk程序并返回到命令行界面提示符下。
3 使用數(shù)據(jù)字段變量
gawk的主要特性之一是其處理文本文件中數(shù)據(jù)的能力。它會(huì)自動(dòng)給一行的每個(gè)數(shù)據(jù)元素分配一個(gè)變量。默認(rèn)情況下,gawk會(huì)將如下變量分配給他在文本行中發(fā)現(xiàn)的數(shù)據(jù)字段。
$0代表整個(gè)文本行
$1代表文本行中的第一個(gè)數(shù)據(jù)字段。
$2代表文本行中的第二個(gè)數(shù)據(jù)字段
$N代表文本行中的第N個(gè)數(shù)據(jù)字段
? ?在文本行中,沒(méi)個(gè)數(shù)據(jù)字段都是通過(guò)字段分隔符劃分的。gawk在讀取一行文本時(shí),會(huì)用預(yù)定義的字段分隔符劃分沒(méi)個(gè)數(shù)據(jù)字段。gawk中默認(rèn)吧的字段分隔符是任意的空白字符(例如空格或者制表符)
在下面例子中,gawk程序讀取文本文件,只顯示第一個(gè)數(shù)據(jù)字段的值。
cat data2.txt
gawk '{print $1}' data2.txt
One
Two
Three
該程序用$1字段變量來(lái)僅顯示每行文本的第1個(gè)數(shù)據(jù)字段。
如果你要讀取采用了其他字段分隔符的文件,可以用-F選項(xiàng)指定。
$gawk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
postfix
sshd
chrony
tcpdump
mysql
dockerroot
這個(gè)簡(jiǎn)短的程序顯示了系統(tǒng)中密碼文件中的第一個(gè)數(shù)據(jù)字段。由于/ect/passwd文件用冒號(hào)來(lái)分割數(shù)據(jù)字段,因而如果要?jiǎng)澐置總€(gè)數(shù)據(jù)元素,則必須在gawk選項(xiàng)中將冒號(hào)指定為字段分隔符。
4. 在程序腳本中使用多個(gè)命令
? ? 如果一種編程語(yǔ)言只能執(zhí)行一條命令,那么它不會(huì)有太大可用性。gawk編程語(yǔ)言允許你將多條命令組合成一個(gè)正常的程序。要在命令行的程序腳本中使用多條命令,只要在命令之間放個(gè)分號(hào)即可。
echo "My name is Rich" ?| gawk '{$4="Chritine"; print $0}'
My name is Chritine
? ? ?第一條命令會(huì)給字段變量$4賦值。第二條命令會(huì)打印整個(gè)數(shù)據(jù)字段。注意,gawk程序在輸出中已經(jīng)將原文本中的第四個(gè)數(shù)據(jù)字段替換成了新值。
? ?也可以用次提示符一行一行地輸入程序腳本命令。
?gawk '{
> $4="Chritine"
> print $0}'
My name is Rich
My name is Chritine
?
在你使用了表示起始的單引號(hào)后,bash shell 會(huì)使用次提示符來(lái)提示你輸入更多數(shù)據(jù)。你可以每次在每行加一條命令,直到輸入結(jié)尾的單引號(hào)。因?yàn)闆](méi)有在命令行中指定文件名,gawk程序會(huì)從STDIN中獲得數(shù)據(jù)。當(dāng)運(yùn)行這個(gè)程序結(jié)束的時(shí)候,它會(huì)等著讀取來(lái)自STDIN的文本,要退出程序,只需要按下CTRL+D組合鍵來(lái)表名數(shù)據(jù)結(jié)束。
5. 從文件中讀取程序
跟sed編輯器一樣,gawk編輯器允許將程序存儲(chǔ)到文件中,然后再在命令行中引用。
cat script2.gawk
{print $1 "'s home directory is " $6}
?
?gawk -F: -f script2.gawk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
sync's home directory is /sbin
shutdown's home directory is /sbin
?
script2.gawk程序腳本會(huì)再次使用print命令打印/etc/passwd文件的主目錄數(shù)據(jù)字段(字段變量$6),以及userid數(shù)據(jù)字段(字段變量$1)。
可以在程序文件中指定多條命令。要這么做的話(huà),只要一條命令放一行即可,不需要使用分號(hào)。
cat script3.gawk
{
text = "'s home directory is "
print $1 text $6
}
?
awk -F: -f script3.gawk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
sync's home directory is /sbin
shutdown's home directory is /sbin
halt's home directory is /sbin
mail's home directory is /var/spool/mail
? ?script3.gawk程序腳本定義了一個(gè)變量來(lái)保存print命令中用到的文本字符串。注意,gawk程序在引用變量值并未像shell腳本一樣使用美元符。
6. 在處理數(shù)據(jù)前運(yùn)行腳本
? gawk還允許指定程序腳本何時(shí)運(yùn)行。默認(rèn)情況下,gawk會(huì)從輸入中讀取一行文本,然后針對(duì)改行的數(shù)據(jù)執(zhí)行程序腳本。有時(shí)可能需要在處理數(shù)據(jù)前運(yùn)行腳本,比如為報(bào)告創(chuàng)建標(biāo)題。BEGIN關(guān)鍵字就是用來(lái)做這個(gè)的。它會(huì)強(qiáng)制gawk在讀取數(shù)據(jù)前執(zhí)行BEGIN關(guān)鍵字后制定的程序腳本。
?gawk 'BEGIN {print "Hello World"}'
Hello World
這次print命令會(huì)在讀取數(shù)據(jù)前顯示腳本。但它顯示了文本后,它會(huì)快速推出,不等待任何數(shù)據(jù)。如果想使用正常的程序腳本中處理數(shù)據(jù),必須用另一個(gè)腳本區(qū)域來(lái)定義程序。
?
?
?
?
?
總結(jié)
- 上一篇: win10 tensorflow MTC
- 下一篇: ARP断网攻击(详细教程)