shell awk正則式匹配問題

2021-06-17 22:20:47 字數 1886 閱讀 4127

今天看到個shell指令碼裡面awk處理字串的,裡面有一句gsub("\\.[0-9]+$","",$2),而這個$2的格式是2013-08-07 00:12:13.333這種,這個gsub想要把.333給去掉,看著不太正常,感覺裡面的正則式應該是匹配不到.333的啊。\\轉義後就變成了乙個\,而原來的.是沒有被轉義的,這樣就應該無法擷取掉.333的,可實際執行了一下,的確可以正確執行,然後又去掉乙個\試了下,也可以,但是提示awk: warning: escape sequence `\.' treated as plain `.'

對於 awk 程式中的pattern,用"//"包圍即可,比如

mount |awk '/type (ext3|tmpfs)/ '

分隔符(field separator)也支援正規表示式,它在 awk 程式中是乙個名為 fs 的變數,可以在命令列中通過 -f 引數設定 fs 變數的值,比如

awk -f '[:/]' ''

如果方括號本身就是分隔符,比如想提取日誌中用包圍的時間戳,就需要非常小心地使用引號和轉義,因為shell會搶先轉義。

通過試驗,我發現這裡面有三層轉義,按執行順序依次是:

shell

awkfield separator processor

要禁止shell轉義,請用單引號包圍 fs 的值,否則使用雙引號或乾脆不用引號(僅當引數不包含空格時)。

awk的轉義是無法禁止的,所以只能通過累加轉義來抵消它的影響,也就是用 '\\' 表達 '\'。

field separator processor 是我想象出來的乙個東西,總之我們的目的就是讓 fs 的值正好就是最根本的那個正規表示式。

以下是一些示例,正反面都有。示例程式的任務是從"[234 abc] lalala"中提取出"234 abc"。

(1) 失敗,"[\[\]]" 被 awk 轉義成 "" 了

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f '[\[\]]' ''   

awk: warning: escape sequence `\[' treated as plain `['

awk: warning: escape sequence `\]' treated as plain `]'

(2) 成功,"[\\[\\]]" 被 awk 轉義成 "[\[\]]" 了,而這正是我們想要的結果

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f '[\\[\\]]' '' 

234 abc

(3) 失敗,"[\\[\\]]" 先被 shell 轉移成 "[\[\]]",再被 awk 轉義成 "" 了

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f "[\\[\\]]" ''  

awk: warning: escape sequence `\[' treated as plain `['

awk: warning: escape sequence `\]' treated as plain `]'

(4) 成功,"[\\\\[\\\\]]" 先被 shell 轉義成 "[\\[\\]]",再被 awk 轉義成 "[\[\]]"

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f "[\\\\[\\\\]]" ''

234 abc

(5) 成功,跟(4)的原理相同

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f [\\\\[\\\\]] ''

234 abc

(6) 成功,原理我就不明白了,在論壇裡看到的,由它還可以衍生出很多變種

[pzy@vm ~]$ echo "[234 abc] lalala" | awk -f ''   

234 abc

正則式匹配問題

請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配。樣例輸入 s aa p a ...

js 日期匹配正則式

檢驗字串中是否包含1900 2050的日期子字串 var datereg null ymd new regexp 2 9 0 9 1 6 9 0 9 1 0 2 0?1 9 2 0 8 1 0 9 0?1 9 1 0 2 0?13 9 29 30 1 02 0?13578 31 1 6 9 2 9 ...

Python 正則匹配問題

前幾天,在用python正則做乙個匹配關鍵字的事情,發現了一些問題,順便提供一些解決方法。使用的是python re module re.search 與 re.match的區別 re.match 函式 總是從字串 開頭匹配 並返回匹配的字串的 match 物件 re.search 函式 對整個字串...