在這一部分,我們将會進入 awk 更進階的部分,使用 awk 處理更複雜的文本和進行字元串過濾操作。是以,我們将會講到 awk 的一些特性,諸如變量、數值表達式和指派運算符。
學習 awk 變量,數值表達式和指派運算符
你可能已經在很多程式設計語言中接觸過它們,比如 shell,c,python 等;這些概念在了解上和這些語言沒有什麼不同,是以在這一小節中你不用擔心很難了解,我們将會簡短的提及常用的一些 awk 特性。
這一小節可能是 awk 指令裡最容易了解的部分,是以放松點,我們開始吧。
<a target="_blank"></a>
在很多程式設計語言中,變量就是一個存儲了值的占位符,當你在程式中建立一個變量的時候,程式一運作就會在記憶體中建立一些空間,你為變量賦的值會存儲在這些記憶體空間上。
你可以像下面這樣定義 shell 變量一樣定義 awk 變量:
<code>variable_name=value</code>
上面的文法:
<code>variable_name</code>: 為定義的變量的名字
<code>value</code>: 為變量賦的值
再看下面的一些例子:
<code>computer_name=”tecmint.com”</code>
<code>port_no=”22”</code>
<code>email=”[email protected]”</code>
<code>server=computer_name</code>
觀察上面的簡單的例子,在定義第一個變量的時候,值 'tecmint.com' 被賦給了 'computer_name' 變量。
此外,值 22 也被賦給了 port_no 變量,把一個變量的值賦給另一個變量也是可以的,在最後的例子中我們把變量 computer_name 的值賦給了變量 server。
<code>first_name=$2</code>
<code>second_name=$3</code>
在上面的例子中,變量 first_name 的值設定為第二個字段,second_name 的值設定為第三個字段。
<code>$ cat names.txt</code>
使用 cat 指令檢視清單檔案内容
然後,我們也可以使用下面的 awk 指令把清單中第一個使用者的第一個和第二個名字分别存儲到變量 first_name 和 second_name 上:
<code>$ awk '/aaron/{ first_name=$2 ; second_name=$3 ; print first_name, second_name ; }' names.txt</code>
使用 awk 指令為變量指派
再看一個例子,當你在終端運作 'uname -a' 時,它可以列印出所有的系統資訊。
第二個字段包含了你的主機名,是以,我們可以像下面這樣把它賦給一個叫做 hostname 的變量并且用 awk 列印出來。
<code>$ uname -a</code>
<code>$ uname -a | awk '{hostname=$2 ; print hostname ; }'</code>
使用 awk 把指令的輸出賦給變量
在 awk 中,數值表達式使用下面的數值運算符組成:
<code>*</code> : 乘法運算符
<code>+</code> : 加法運算符
<code>/</code> : 除法運算符
<code>-</code> : 減法運算符
<code>%</code> : 取模運算符
<code>^</code> : 指數運算符
數值表達式的文法是:
<code>$ operand1 operator operand2</code>
上面的 operand1 和 operand2 可以是數值和變量,運算符可以是上面列出的任意一種。
下面是一些展示怎樣使用數值表達式的例子:
<code>counter=0</code>
<code>num1=5</code>
<code>num2=10</code>
<code>num3=num2-num1</code>
<code>counter=counter+1</code>
要了解 awk 中數值表達式的用法,我們可以看看下面的例子,檔案 domians.txt 裡包括了所有屬于 tecmint 的域名。
<code>news.tecmint.com</code>
<code>tecmint.com</code>
<code>linuxsay.com</code>
<code>windows.tecmint.com</code>
可以使用下面的指令檢視檔案的内容:
<code>$ cat domains.txt</code>
檢視檔案内容
如果想要計算出域名 tecmint.com 在檔案中出現的次數,我們就可以通過寫一個簡單的腳本實作這個功能:
<code>#!/bin/bash</code>
<code>for file in $@; do</code>
<code>if [ -f $file ] ; then</code>
<code>#print out filename</code>
<code>echo "file is: $file"</code>
<code>#print a number incrementally for every line containing tecmint.com</code>
<code>awk '/^tecmint.com/ { counter=counter+1 ; printf "%s\n", counter ; }' $file</code>
<code>else</code>
<code>#print error info incase input is not a file</code>
<code>echo "$file is not a file, please specify a file." >&2 && exit 1</code>
<code>fi</code>
<code>done</code>
<code>#terminate script with exit code 0 in case of successful execution</code>
<code>exit 0</code>
計算一個字元串或文本在檔案中出現次數的 shell 腳本
寫完腳本後儲存并賦予執行權限,當我們使用檔案運作腳本的時候,檔案 domains.txt 作為腳本的輸入,我們會得到下面的輸出:
<code>$ ./script.sh ~/domains.txt</code>
計算字元串或文本出現次數的腳本
從腳本執行後的輸出中,可以看到在檔案 domains.txt 中包含域名 tecmint.com 的地方有 6 行,你可以自己計算進行驗證。
我們要說的最後的 awk 特性是指派操作符,下面列出的隻是 awk 中的部分指派運算符:
<code>*=</code> : 乘法指派操作符
<code>+=</code> : 加法指派操作符
<code>/=</code> : 除法指派操作符
<code>-=</code> : 減法指派操作符
<code>%=</code> : 取模指派操作符
<code>^=</code> : 指數指派操作符
下面是 awk 中最簡單的一個指派操作的文法:
<code>$ variable_name=variable_name operator operand</code>
例子:
<code>num=20</code>
<code>num=num-1</code>
你可以使用在 awk 中使用上面的指派操作符使指令更簡短,從先前的例子中,我們可以使用下面這種格式進行指派操作:
<code>variable_name operator=operand</code>
<code>counter+=1</code>
<code>num-=1</code>
是以,我們可以在 shell 腳本中改變 awk 指令,使用上面提到的 += 操作符:
<code>awk '/^tecmint.com/ { counter+=1 ; printf "%s\n", counter ; }' $file</code>
修改了的 shell 腳本
這些概念和其他的程式設計語言沒有任何不同,但是可能在 awk 中有一些意義上的差別。
原文釋出時間為:2016-08-06
本文來自雲栖社群合作夥伴“linux中國”