【问题标题】:Return line number with Ruby readline使用 Ruby readline 返回行号
【发布时间】:2019-04-25 19:01:13
【问题描述】:

寻找一个简单的 ruby​​/bash 解决方案来调查一个日志文件,例如一个 apache 访问日志。

我的日志包含以“authorization:”开头的行

脚本的目标是在匹配之后返回整个下一行,其中包含字符串“x-forwarded-for”。

host: 10.127.5.12:8088^M
accept: */*^M
date: Wed, 19 Apr 2019 22:12:36 GMT^M
authorization: FOP ASC-amsterdam-b2c-v7:fkj9234f$t34g34rf=^M
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0)
x-forwarded-for: 195.99.33.222, 10.127.72.254^M
x-forwarded-host: my.luckyhost.com^M
x-forwarded-server: server.luckyhost.de^M
connection: Keep-Alive^M
^M

我的问题与 if 条件有关。 如何从 readline 获取行号/调用方,并在第二步中使用 x-forwarded-for 返回整个下一行。

file = File.open(args[:apache_access_log], "r")
log_snapshot = file.readlines
file.close

log_snapshot.reverse_each do |line|
  if line.include? "authorization:"
    puts line

  end
end

【问题讨论】:

  • stackoverflow.com/q/3024372/23915 在这个线程中有一些替代方法可以有效地向后读取文件,因为将整个日志文件加载到内存中,然后反转它,并迭代以获取最后几行可能非常困难在您的系统上。
  • 我不太确定这是否是您想要的,但运行 grep --line-number --after-context 1 logfile.txt(对于 *xoid 系统)并使用您的 ruby​​ 脚本消耗其输出可能在计算和可维护性方面更便宜。跨度>
  • 我不明白你的问题。在您的示例中,您是否希望检索 "authorization: FOP...""user-agent: Mozilla/5.0...""x-forwarded-for:..." 这三行以及其中第一行的行号?你说你的文件包含(原文如此)'以"authorization:"' 开头的行,而不是'a line" beginning...'。如果有多个怎么办?你想要最后一个吗?如果是这样,你知道它是否会在文件末尾附近吗?最后,一般来说,日志文件有多大?是否可以读取整个文件,或者为了提高效率,您希望只读取文件的末尾?

标签: ruby readline


【解决方案1】:

也许是这样的:

log_snapshot.each_with_index.reverse_each do |line, n|
  case (line)
  when /authorization:/
    puts '%d: %s' % [ n + 1, line ]
  end
end

each_with_index 用于生成以 0 为索引的行号。我已切换到case 样式,因此您可以更灵活地匹配不同的条件。例如,您可以添加 /i 标志以非常轻松地进行不区分大小写的匹配,或者在开头添加 \A 以将其锚定在字符串的开头。

File.open 使用block 方法要考虑的另一件事,像这样:

File.open(args[:apache_access_log], "r") do |f|
  f.readlines.each_with_index.reverse_each do |line, n|
    # ...
  end
end

无需显式调用close。块的末尾会自动为您关闭它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多