Awk
如何在 awk if 語句中使用星號
我有一個場景,我需要列印一行,但是如果使用 awk 來搜尋一個數字,則會附加一個帶有更多數字的雙冒號:
請參見下面的範例:
test1 test2 37:375003 test3 test4 test1 test2 38:375004 test3 test4 test1 test2 39:375005 test3 test4 test1 test2 40:375006 test3 test4 test1 test2 41:375007 test3 test4
我想要實現的是使用如下命令:
cat test_out.txt | awk "{if ($3 == 37~/\:*/ ) print $0;}"
以上應該給我以下行:
test1 test2 37:375003 test3 test4
得到以下語法錯誤:
Syntax Error The source line is 1. The error context is {if ( >>> == <<< awk: 0602-502 The statement cannot be correctly parsed. The source line is 1.
您需要使用
~
二元運算符,其語法為:string ~ regexp
要將字元串與正則表達式匹配,因此:
<test_out.txt awk '$3 ~ /^37:[[:digit:]]+$/'
列印第三個欄位與擴展正則表達式匹配的記錄(預設操作的
{print}
縮寫)。{print $0}``^37:[[:digit:]]+$
在 ERE 語法中:
^
在主題的開頭匹配[...]
: 匹配集合中的任何字元或排序元素。[:digit:]
在上面的集合中表示在區域設置中分類為十進制數字的任何字元(在大多數係統上,僅限於 0123456789)。更改為0123456789
inmawk
which 不支持那些 POSIX 字元類,或者如果您不想匹配其他十進制數字。0-9
也可以工作,mawk
但也可以在某些awk
實現中匹配其他字元。+
是針對前面的一個或多個。所以這裡有一個或多個數字$
匹配在主題的末尾。如果您不關心後面的部分
37:
是否由數字組成,那麼正則表達式只是^37:
(37:
在主題的開頭)。另一種方法是:
<test_out.txt awk '$3 + 0 == 37'
數字
+ 0
運算強制awk
嘗試轉換$3
為數字,忽略初始數字之後的任何內容。然後這將匹配37:anything
,但也匹配37.0;whatever
¹,3.7e+1
¹,可能0x25#xxx
與某些awk
實現,+37+38
…+$3 == 37
雖然使用標準,但不適用於某些awk
實現。
37
對於來自 shell 變數的值(此處),您可以在 shell 中構造正則表達式並awk
通過ENVIRON
ment 變數將其傳遞給:var=37 ERE='^'$var':[[:digit:]]+$' <test_out.txt awk '$3 ~ ENVIRON["ERE"]'
或者
awk
v
從 shell 變數中創建一個變數²:var=37 <test_out.txt awk -v n="$var" '$3 ~ "^" n ":[[:digit:]]+"'
避免將 shell 變數擴展到
awk
程式碼中,如下所示:<test_out.txt awk '$3 ~ /^'"$var"':[[:digit:]]+$/'
因為這通常會引入命令注入漏洞(最嚴重的漏洞類型)。
對您的嘗試的一些評論:
- 正如@RudyC已經指出的那樣,您在 awk 程式碼周圍使用了雙引號。Shell 在其中執行參數擴展,因此
$3
將擴展為 shell 腳本的第三個參數的值,以及腳本$0
的名稱。$3 == 37 ~ /\:*/
.==
的優先級高於~
。就是這樣($3 == 37) ~ /\:*/
。這就是將正則\:*
表達式與該比較的結果相匹配(1 或 0,取決於是否$3
為 37)\:*
因為正則表達式未指定,因為\:
未指定。要匹配文字:
,它是:
單獨的。:*
將是 0 或更多:
s 所以匹配任何東西,因為任何字元串都包含至少 0:
s。*
在正則表達式中匹配 0 個或多個先前的事物。*
您可能會將其與匹配 0 個或更多字元的 shell 萬用字元混淆。在正則表達式中,0 個或多個字元是.*
,.
是匹配單個字元的運算符。awk
語句的形式為condition {action}
,其中條件或動作都可以省略。在您的情況下,您省略了條件並if
在操作中使用,而使用{print $0}
恰好是預設操作。雖然這很有效,但對使用者來說這將非常awk
謹慎awk
。- 您過去
cat
常常cat
合併一個幾乎沒有意義的文件。shell 可以自己打開文件,使其成為awk
使用重定向的標準輸入,從而節省了程序和通過管道推送內容的需要。您還可以將文件名作為參數傳遞給awk
它也可以自己打開它。¹假設十進制基數字元在語言環境中
.
而不是,
在語言環境中,至少對於某些awk
實現,例如awk
POSIX 模式下的 GNU。² 請注意會
-v
破壞反斜杠,因此ENVIRON
在一般情況下使用更安全。