首頁 >系統教程 >Linux >如何利用 awk 的特殊模式 BEGIN 和 END 進行處理

如何利用 awk 的特殊模式 BEGIN 和 END 進行處理

WBOY
WBOY轉載
2024-01-02 18:06:07847瀏覽

在 awk 系列的第八節,我們介紹了一些強大的 awk 指令功能,它們是變數、數字運算式和賦值運算子。

本節我們將學習更多的 awk 功能,也就是 awk 的特殊模式:BEGINEND

隨著我們逐漸展開,並探索更多建構複雜 awk 操作的方法,將會證明 awk 的這些特殊功能的是多麼強大。

開始前,先讓我們回顧一下 awk 系列的介紹,記得當我們開始這個系列時,我就指出 awk 指令的通用語法是這樣的:

# awk 'script' filenames  

在上述語法中,awk 腳本擁有這樣的形式:

/pattern/ { actions } 

你通常會發現腳本中的模式(/pattern )是正規表示式,此外,你也可以在這裡用特殊模式 BENGINEND 。因此,我們也能按照下面的形式寫出一條 awk 指令:

awk '
BEGIN { actions } 
/pattern/ { actions }
/pattern/ { actions }
……….
END { actions } 
' filenames  

假如你在 awk 腳本中使用了特殊模式:BEGINEND ,以下則是它們對應的含義:

  • BEGIN 模式:是指 awk 將在讀取任何輸入行之前立即執行BEGIN 中指定的動作。
  • END 模式:是指 awk 將在它正式退出前執行 END中指定的動作。

含有這些特殊模式的 awk 指令腳本的執行流程如下:

  1. 當腳本中使用了 BEGIN 模式,則 BEGIN 中所有的動作都會在讀取任何輸入行之前執行。
  2. 然後,讀入一個輸入行並解析成不同的段。
  3. 接下來,每一條指定的非特殊模式都會和輸入行進行比較匹配,當匹配成功後,就會執行模式對應的動作。對所有你指定的模式重複此執行該步驟。
  4. 再接下來,對於所有輸入行重複執行步驟 2 和 步驟 3。
  5. 當讀取並處理完所有輸入行後,假如你指定了 END 模式,那麼將會執行對應的動作。

當你使用特殊模式時,想要在 awk 操作中獲得最好的結果,你應該記住上面的執行順序。

為了方便理解,讓我們使用第八節的例子進行演示,那個例子是關於 Tecmint 擁有的域名列表,並保存在一個叫做 domains.txt 的文件中。

news.tecmint.com
tecmint.com
linuxsay.com
windows.tecmint.com
tecmint.com
news.tecmint.com
tecmint.com
linuxsay.com
tecmint.com
news.tecmint.com
tecmint.com
linuxsay.com
windows.tecmint.com
tecmint.com
$ cat ~/domains.txt

如何使用 awk 的特殊模式 BEGIN 与 END

#查看文件內容

#在這個範例中,我們希望統計出 domains.txt 檔案中網域名稱tecmint.com 出現的次數。所以,我們寫了一個簡單的 shell 腳本來幫助我們完成任務,它使用了變數、數學表達式和賦值運算子的思想,腳本內容如下:

#!/bin/bash
for file in $@; do
if [ -f $file ] ; then
### 输出文件名
echo "File is: $file"
### 输出一个递增的数字记录包含 tecmint.com 的行数
awk '/^tecmint.com/ { counter+=1 ; printf "%s/n", counter ; }' $file
else
### 若输入不是文件,则输出错误信息
echo "$file 不是一个文件,请指定一个文件。" >&2 && exit 1
fi
done
### 成功执行后使用退出代码 0 终止脚本
exit 0

現在讓我們像下面這樣在上述腳本的 awk 指令中應用這兩個特殊模式:BEGINEND

我們應該把腳本:

awk '/^tecmint.com/ { counter+=1 ; printf "%s/n", counter ; }' $file

改成:

awk ' BEGIN {  print "文件中出现 tecmint.com 的次数是:" ; }
/^tecmint.com/ {  counter+=1  ;  }
END {  printf "%s/n",  counter  ; } 
'  $file

在修改了 awk 命令之后,现在完整的 shell 脚本就像下面这样:

#!/bin/bash
for file in $@; do
if [ -f $file ] ; then
### 输出文件名
echo "File is: $file"
### 输出文件中 tecmint.com 出现的总次数
awk ' BEGIN {  print "文件中出现 tecmint.com 的次数是:" ; }
/^tecmint.com/ {  counter+=1  ;  }
END {  printf "%s/n",  counter  ; } 
'  $file
else
### 若输入不是文件,则输出错误信息
echo "$file 不是一个文件,请指定一个文件。" >&2 && exit 1
fi
done
### 成功执行后使用退出代码 0 终止脚本
exit 0

如何使用 awk 的特殊模式 BEGIN 与 END

awk 模式 BEGIN 和 END

当我们运行上面的脚本时,它会首先输出 domains.txt 文件的位置,然后执行 awk 命令脚本,该命令脚本中的特殊模式 BEGIN 将会在从文件读取任何行之前帮助我们输出这样的消息“文件中出现 tecmint.com 的次数是: ”。

接下来,我们的模式/^tecmint.com/ 会在每个输入行中进行比较,对应的动作{ counter+=1 ; } 会在每个匹配成功的行上执行,它会统计出 tecmint.com 在文件中出现的次数。

最终,END 模式将会输出域名 tecmint.com 在文件中出现的总次数。

$ ./script.sh ~/domains.txt 

如何使用 awk 的特殊模式 BEGIN 与 END

用于统计字符串出现次数的脚本

最后总结一下,我们在本节中演示了更多的 awk 功能,并学习了特殊模式 BEGINEND 的概念。

正如我之前所言,这些 awk 功能将会帮助我们构建出更复杂的文本过滤操作。第十节将会给出更多的 awk 功能,我们将会学习 awk 内置变量的思想,所以,请继续保持关注。


以上是如何利用 awk 的特殊模式 BEGIN 和 END 進行處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:linuxprobe.com。如有侵權,請聯絡admin@php.cn刪除