6

我目前正在通过 ARGV 打开在运行时获取的文件:

File.open(ARGV[0]) do |f|
  f.each_line do |line|

一旦找到匹配项,我就会向用户打印输出。

if line.match(/(strcpy)/i)
   puts "[!] strcpy does not check for buffer overflows when copying to destination."
   puts "[!] Consider using strncpy or strlcpy (warning, strncpy is easily misused)."
   puts " #{line}"
end

我想知道如何打印 (ARGV[0]) 文件中匹配行的行号。

Usingprint __LINE__显示来自 Ruby 脚本的行号。我print __LINE__用不同的字符串插值尝试了许多不同的变体,#{line}但没有成功。有没有办法可以从文件中打印出行号?

4

1 回答 1

10

当 Ruby 的 IO 类打开一个文件时,它会将$.全局变量设置为 0。对于读取的每一行,该变量都会递增。因此,要知道读取了哪一行,只需使用$..

英语模块中查找$.or $INPUT_LINE_NUMBER

我们也可以使用lineno属于 IO 类的方法。我发现这有点令人费解,因为我们需要一个 IO 流对象来附加它,而它$.总是可以工作的。

我会更简单地编写循环:

File.foreach(ARGV[0]) do |line|

需要考虑的是,如果您在 *nix 系统上,您可以使用操作系统的内置grepfgrep工具来大大加快您的处理速度。“grep”系列应用程序为做你想做的事进行了高度优化,可以找到所有出现的地方,只有第一个,可以使用正则表达式或固定字符串,并且可以使用 Ruby%x或反引号运算符轻松调用。

puts `grep -inm1 abacus /usr/share/dict/words`

哪个输出:

34:abacus

-inm1表示“忽略字符大小写”、“输出行号”、“第一次出现后停止”

于 2013-10-04T04:54:22.730 回答