我正在嘗試獲取有關某些調試輸出的一些瑣碎統計數據。
每條調試行的形式如下(class name)(delimiter 1)(object ID)(delimiter 2)(method name)(delimiter 3)(log message)
我想計算有多少行來自哪些方法。
本質上,如果每一行都可以減少到(class name)(delimiter)(method name)
,我想知道日誌檔案中每個減少出現了多少次。
我可以在 Bash 中運行什麼命令來進行計數?
(我在 macOS 上使用 macports 用 GNU 工具取代了大多數預設的 BSD 風格工具。)
我可以使用 提取類別名稱grep -o -E "^.*(delimiter 1)
,或使用 提取方法名稱grep -o -E "(delimiter 2).*(delimiter 3)"
,或使用 突出顯示兩者grep --color=always -E "^.*(delimiter 1)|(delimiter 2).*(delimiter 3)"
。我一直在尋找一種方法來只grep
輸出兩個匹配項,然後可以運行它們來| uniq -c
進行計數。
有沒有辦法grep
列印每行的兩個匹配項,而不是只列印一個匹配項或整行?
答案1
本質上,它可以通過
sed -r -n 's/(^.*)(delimiter 1)(.*)(delimiter 2)(.*)(delimiter 3)(.+$)/\1(delimiter)\5/p' <( command that generates debug logs ) | sort | uniq -c | sort -rn
(改編自這裡)
.*
可能匹配太多;sed
是貪婪的並且希望儘早匹配盡可能多的內容,因此這些可能需要例如分隔符的否定(如果您有不方便的分隔符,這可能會很複雜)- 從 到
^
很$
重要,如果您的表達式不匹配,整行將sed
在輸出中包含不匹配的部分 - 僅在類別名稱和方法名稱周圍需要括號;刪除其他意味著更改末尾的數字,因為這些數字按順序引用括號內的子表達式。 (將它們全部納入可以顯示輸出中發生的更多內容
sed
,例如透過將結尾變更為/\1(delimiter)\5 -- \1\2\3\4\5\6\7/p
) sort
必須先運行,uniq -c
因為uniq -c
只計算連續相同行的運行,非連續相同行得到單獨的計數uniq -c
無法替換為,sort -u
因為sort -u
只會刪除重複項,不會對它們進行計數- 最後
sort
不一定要回答問的問題 - 是的,如果你使用正規表示式來解決一個問題,那麼現在你有兩個問題。