我需要從服務器的訪問日志中獲取正在訪問服務器的唯一客戶端計算機名稱/IP 地址的串列。
目標日志行如下所示:
2020-11-17 15:34:04.208 -0500 Information 94 XYZ-ASDF-FMP123 Client "%USERNAME% (QWER-L1212-W6) [11.22.333.44]" opening database "databasename" as "username".
在此示例中,字串(QWER-L1212-W6) [11.22.333.44]將是客戶端計算機/IP 地址的唯一實體的示例。
所以結果會是這樣的:
(QWER-L1212-W6) [11.22.333.44]
(QWER-L1234-W7) [11.22.333.55]
etc...
我試過這個沒有成功:
grep --only-matching '\(. \) \[. \]' | sort --unique Access.log
匹配失敗并回傳整個日志行。
uj5u.com熱心網友回復:
請注意,您使用的是 POSIX BRE 正則運算式風格,因為您沒有傳遞-E/-r也沒有-P選項來更改默認的正則運算式風格。\(...\)在 POSIX BRE 中定義一個捕獲組。不過這里還有更多問題。
你需要使用
grep -o '([^()]*) \[[^][]*]' Access.log | sort -u
注意輸入檔案引數的位置grep。
這([^()]*) \[[^][]*]是一個匹配的 POSIX BRE 模式
(- 文字(字符(a\(是捕獲組的開始)[^()]*(- 除了and之外的零個或多個字符))- 文字)字符(a\)是捕獲組的結尾)- 空間\[- 一個[字符[^][]*[- 除了and之外的零個或多個字符]]- 一個]字符。
查看在線演示:
#!/bin/bash
s='2020-11-17 15:34:04.208 -0500 Information 94 XYZ-ASDF-FMP123 Client "%USERNAME% (QWER-L1212-W6) [11.22.333.44]" opening database "databasename" as "username".'
grep -o '([^()]*) \[[^][]*]' <<< "$s" | sort -u
# => (QWER-L1212-W6) [11.22.333.44]
uj5u.com熱心網友回復:
grep --only-matching '\(. \) \[. \]' file.log
這是失敗的,因為您沒有使用 ERE(擴展正則運算式或-E)grep并且 沒有轉義。因此,對于您的情況,以下可能有效:
grep -E --only-matching '\(. \) \[. \]' file.log
然而,這個正則運算式是有問題的,因為在匹配 close和 closing. 之前將匹配任何字符的 1 。如果您的日志中有這樣的子字串:)](...) [...]
2020-11-17 15:34:04.208 -0500 Information 94 XYZ-ASDF-FMP123 Client "%USERNAME% (QWER-L1212-W6) [11.22.333.44]" opening database "databasename" as "username".
2020-11-17 15:34:04.208 -0500 Information 94 XYZ-ASDF-FMP123 Client "%USERNAME% (QWER-L1212-W6) [21.22.333.33]" opening database "databasename" as "username" (QWER-L1234-W7) [11.22.333.55]
然后你會得到不正確的結果。不正確的結果也將顯示為'([^()]*) \[[^][]*]'。
由于您使用的是欄位的格式和位置是固定的,因此使用這種提取access.log更安全有效,如下所示:awk
awk -F '"' '{sub(/^[^ ]* /, "", $2); print $2}' file.log
(QWER-L1212-W6) [11.22.333.44]
(QWER-L1212-W6) [21.22.333.33]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/437268.html
上一篇:浮點或字串的正則運算式
