默认情况下,Ruby以缓冲模式打开$stdin和$stdout.这意味着您不能使用Ruby来执行类似grep的操作过滤文本.有没有办法强制Ruby使用面向行的模式?我看到了各种解决方案,包括popen3(仅限缓冲模式)和pty(不需要单独处理$stdout和$stderr,我需要).
我该如何做? Python似乎有同样的缺点.
解决方法
看起来你最好打赌是使用STDOUT.syswrite和STDOUT.sysread – 以下似乎有相当不错的性能,尽管是丑陋的代码:
STDIN.sync = true STDOUT.syswrite "Looking for #{ARGV[0]}\n" def next_line mybuff = @overflow || "" until mybuff[/\n/] mybuff += STDIN.sysread(8) end overflow = mybuff.split("\n") out,*others = overflow @overflow = others.join("\n") out rescue EOFError => e false # NB: There's a bug here,see below end line = next_line while line STDOUT.syswrite "#{line}\n" if line =~ /#{ARGV[0]}/i line = next_line end
注意:不确定你需要#sysread #sync,但如果是这样,你也应该同步STDOUT.此外,它一次读取8个字节到mybuff中 – 你应该尝试这个值,它的效率很低/ cpu很重.最后,这段代码是hacky,需要一个重构,但它的工作原理 – 使用ls -l〜/ * |进行测试ruby rgrep.rb doc(其中’doc’是搜索词)
第二个注意事项:显然,我很忙,试图让它表现很好,我没能让它执行正常!由于Dmitry Shevkoplyas有noted,如果在EOFError被提出时,在@overflow中有文本,该文本将会丢失.我相信如果用以下代码替换catch,那么它应该解决问题:
rescue EOFError => e return false unless @overflow && @overflow.length > 0 output = @overflow @overflow = "" output end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。