精通awk系列(17):awk布爾值、比較和邏輯運算

来源:https://www.cnblogs.com/f-ck-need-u/archive/2020/02/29/12381899.html
-Advertisement-
Play Games

回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" awk布爾值 在awk中,沒有像其它語言一樣專門提供true、false這樣的關鍵字。 但它的布爾值邏輯非常簡單: 數值0表示布爾假 空字元串表示布爾假 其餘所有均為布爾真 字元串"0"也是真,因為它是字元串 awk中,正則 ...



回到:


awk布爾值

在awk中,沒有像其它語言一樣專門提供true、false這樣的關鍵字。

但它的布爾值邏輯非常簡單:

  • 數值0表示布爾假
  • 空字元串表示布爾假
  • 其餘所有均為布爾真
    • 字元串"0"也是真,因為它是字元串
  • awk中,正則匹配也有返回值,匹配成功則返回1,匹配失敗則返回0
  • awk中,所有的布爾運算也有返回值,布爾真返回值1,布爾假返回值為0
awk '
BEGIN{
    if(1){print "haha"}
    if("0"){print "hehe"}
    if(a=3){print "hoho"}  # if(3){print "hoho"}
    if(a==3){print "aoao"}
    if(/root/){print "heihei"}  # $0 ~ /root/
}'

awk中比較操作

strnum類型

awk最基本的數據類型只有string和number(gawk 4.2.0版本之後支持正則表達式類型)。但是,對於用戶輸入數據(例如從文件中讀取的各個欄位值),它們理應屬於string類型,但有時候它們看上去可能像是數值(例如$2=37),而有時候有需要這些值是數值類型。

awk的數據來源:

  1. awk內部產生的,包括變數的賦值、表達式或函數的返回值。
  2. 從其它來源獲取到的數據,都是外部數據,也是用戶輸入數據,這些數據理應全部都是string類型的數據。

所以POSIX定義了一個名為"numeric string"的"牆頭草"類型,gawk中則稱為strnum類型。當獲取到的用戶數據看上去是數字時,那麼它就是strnum類型。strnum類型在被使用時會被當作數值類型。

註意,strnum類型只針對於awk中除數值常量、字元串常量、表達式計算結果外的數據。例如從文件中讀取的欄位$1$2、ARGV數組中的元素等等。

$ echo "30" | awk '{print typeof($0) " " typeof($1)}'
strnum strnum
$ echo "+30" | awk '{print typeof($1)}'
strnum
$ echo "30a" | awk '{print typeof($1)}'
string
$ echo "30 a" | awk '{print typeof($0) " " typeof($1)}'
string strnum
$ echo " +30 " | awk '{print typeof($0) " " typeof($1)}'
strnum strnum

大小比較操作

比較操作符:

< > <= >= != ==  大小、等值比較
in     數組成員測試

比較規則:

       |STRING NUMERIC STRNUM
-------|-----------------------
STRING |string string  string
NUMERIC|string numeric numeric
STRNUM |string numeric numeric

簡單來說,string優先順序最高,只要string類型參與比較,就都按照string的比較方式,所以可能會進行隱式的類型轉換。

其它時候都採用num類型比較。

$ echo ' +3.14' | awk '{print typeof($0) " " typeof($1)}'  #strnum strnum
$ echo ' +3.14' | awk '{print($0 == " +3.14")}'    #1
$ echo ' +3.14' | awk '{print($0 == "+3.14")}'     #0
$ echo ' +3.14' | awk '{print($0 == "3.14")}'      #0
$ echo ' +3.14' | awk '{print($0 == 3.14)}'        #1
$ echo ' +3.14' | awk '{print($1 == 3.14)}'        #1
$ echo ' +3.14' | awk '{print($1 == " +3.14")}'    #0
$ echo ' +3.14' | awk '{print($1 == "+3.14")}'     #1
$ echo ' +3.14' | awk '{print($1 == "3.14")}'      #0 
$ echo 1e2 3|awk ’{print ($1<$2)?"true":"false"}’  #false

採用字元串比較時需註意,它是逐字元逐字元比較的。

"11" < "9"  # true
"ab" < 99   # false

邏輯運算

&&          邏輯與
||          邏輯或
!           邏輯取反

expr1 && expr2  # 如果expr1為假,則不用計算expr2
expr1 || expr2  # 如果expr1為真,則不用計算expr2

# 註:
# 1. && ||會短路運算
# 2. !優先順序高於&&和||
#    所以`! expr1 && expr2`等價於`(! expr1) && expr2`

!可以將數據轉換成數值的1或0,取決於數據是布爾真還是布爾假。!!可將數據轉換成等價布爾值的1或0。

$ awk 'BEGIN{print(!99)}'   # 0
$ awk 'BEGIN{print(!"ab")}' # 0
$ awk 'BEGIN{print(!0)}'    # 1
$ awk 'BEGIN{print(!ab)}'   # 1,因為ab變數不存在

$ awk 'BEGIN{print(!!99)}'   # 1
$ awk 'BEGIN{print(!!"ab")}' # 1
$ awk 'BEGIN{print(!!0)}'    # 0
$ awk 'BEGIN{print(!!ab)}'   # 0

由於awk中的變數未賦值時預設初始化為空字元串或數值0,也就是布爾假。那麼可以直接對一個未賦值的變數執行!操作。

下麵是一個非常有意思的awk技巧,它通過多次!對一個flag取反來實現只輸出指定範圍內的行。

# a.txt
$1==1{flag=!flag;print;next}    # 在匹配ID=1的行時,flag=1
flag{print}               # 將輸出ID=2,3,4,5的行
$1==5{flag=!flag;next}    # ID=5時,flag=0

藉此,就可以讓awk實現一個多行處理模式。例如,將指定範圍內的數據保存到一個變數當中去。

$1==1{flag=!flag;next}
flag{multi_line=multi_line$0"\n"}
$1==5{flag=!flag;next}
END{printf multi_line}

運算符優先順序

優先順序從高到低:man awk

()
$      # $(2+2)
++ --
^ **
+ - !   # 一元運算符
* / %
+ -
space  # 這是字元連接操作 `12 " " 23`  `12 " " -23`
| |&
< > <= >= != ==   # 註意>即是大於號,也是print/printf的重定向符號
~ !~
in
&&
||
?:
= += -= *= /= %= ^=

對於相同優先順序的運算符,通常都是從左開始運算,但下麵2種例外,它們都從右向左運算:

  • 賦值運算:如= += -= *=
  • 冪運算
a - b + c  =>  (a - b) + c
a = b = c  =>  a =(b = c)
2**2**3    =>  2**(2**3)

再者,註意print和printf中出現的>符號,這時候它表示的是重定向符號,不能再出現優先順序比它低的運算符,這時可以使用括弧改變優先順序。例如:

awk 'BEGIN{print "foo" > a < 3 ? 2 : 1)'   # 語法錯誤
awk 'BEGIN{print "foo" > (a < 3 ? 2 : 1)}' # 正確

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.ACL許可權簡介與開啟 一.ACL許可權是為瞭解決所有者/所屬組/其他人三種身份不足的問題 二.查看分區ACL許可權是否開啟 dumpe2fs命令是查詢指定分區詳細文件系統信息的命令 dumpe2fs h /dev/sda3 Default mount options: user_xattr acl顯 ...
  • 背景 By 魯迅 By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器,Contex A53,雙核 3. 使用工具:Source Insight 3.5, Visio 1. 概述 進程切換:內核將CPU上正在運行的進程掛起,選擇下一個進程來運行。 ARM架構中,CPU上一次 ...
  • 1. Prometheus配置方式有兩種 命令行,用來配置不可變命令參數,主要是Prometheus運行參數,比如數據存儲位置 配置文件,用來配置Prometheus應用參數,比如數據採集,報警對接 不重啟進程配置生效方式也有兩種 對進程發送信號SIGHUP HTTP POST請求,需要開啟 web ...
  • 簡介:Nextcloud是一款開源免費的私有雲存儲網盤項目,可以讓你快速便捷地搭建一套屬於自己或團隊的雲同步網盤,從而實現跨平臺跨設備文件同步、共用、版本控制、團隊協作等功能。它的客戶端覆蓋了Windows、Mac、Android、iOS、Linux 等各種平臺,也提供了網頁端以及 WebDAV介面 ...
  • Windows操作系統的帳號角色許可權 1.Windows操作系統的帳戶: • Windows操作系統好比一間富麗堂皇的宮殿,大門的門鎖是身份和許可權鑒別器,到訪人員是賬戶,鑰匙是驗證其身份和許可權的措施。 <1.>本地系統帳戶,Local System Account 本地管理員帳戶,Local Adm ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" 數組 awk數組特性: awk的數組是關聯數組(即key/value方式的hash數據結構),索引下標可為數值(甚至是負數、小數等),也可為字元串 在內部,awk數組的索引全都是字元串,即使是數值索引在使用時內部也會轉換成字 ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" break和continue break可退出for、while、do...while、switch語句。 continue可讓for、while、do...while進入下一輪迴圈。 next和nextfile next會 ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" 流程式控制制語句 註:awk中語句塊沒有作用域,都是全局變數。 代碼塊 if...else 搞笑題:妻子告訴程式員老公,去買一斤包子,如果看見賣西瓜的,就買兩個。結果是買了兩個包子回來。 switch...case awk 中的 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...