Bash 指令計算兩個不同位置具有匹配子字串的行數

Bash 指令計算兩個不同位置具有匹配子字串的行數

我正在嘗試獲取有關某些調試輸出的一些瑣碎統計數據。

每條調試行的形式如下(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不一定要回答問的問題
  • 是的,如果你使用正規表示式來解決一個問題,那麼現在你有兩個問題。

相關內容