从一行文本中的 2 个或更多 IP 地址中提取 1 个 IP 地址

Tha*_*Guy 0 text sed

我有大约 30,000 个 Apache 访问日志,其中一些列出了多个客户端 IP 地址。这是因为 Apache 记录了 X-Forwarded-For 标头而不是客户端的 IP 地址。这样做的原因是因为我们最近在 Web 服务器前面添加了 haproxy。

展望未来,我们将使用Apache 的rpaf仅记录 1 个 IP 地址,即到 haproxy 的传入连接的 IP 地址,因此这不会是一个持续的问题。

这让我想到了实际问题:

如何处理具有多个 IP 地址的现有日志,以仅提取我想要的日志。我假设我需要 sed 或类似的东西,但我更像是一个 Windows 人,所以不是 100% 确定。

规则是:

  • 如果只有 1 个 IP,则不会修改该行。
  • 如果有2个或更多IP,我只想保留倒数第二个IP。它们以逗号分隔。

示例 1、1 个 IP

输入:10.1.1.1 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

输出:10.1.1.1 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

示例 2,2 个 IP

输入:10.1.1.1 , 10.2.2.2 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

输出:10.1.1.1 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

示例 3、3 个 IP

输入: 10.1.1.1, 10.2.2.2 , 10.3.3.3 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

输出:10.2.2.2 - - [29/Jan/2010:11:00:00] ....(日志行的其余部分)

Jon*_*rke 6

这可以通过在您的日志上运行此 sed 命令来实现:

sed -i "s/^\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+, \)*\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\), [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+ - -/\2 - -/"
Run Code Online (Sandbox Code Playgroud)

一些解释:

  • 一般格式是 s/MATCH PATTERN/REPLACE PATTERN/
  • 匹配是在字符串“some IP,”(0 到多次)后跟“some IP”(这是我们想要保留的)和最后“some IP - -”(要丢弃的最后一个 IP)上完成的
  • 不需要匹配行的第一种格式(只有一个 IP),因为它不需要更改。
  • 最后一部分包含\2which 指括号中匹配的第二部分。
  • 在 shell 中运行时,必须对许多字符进行转义(使用反斜杠: ),例如方括号:()、加号:(+表示“至少一次”)和文字字符句点:(.否则将被视为通配符)
  • -i选项sed的手段来改变位置的文件。确保您在副本上工作!