用于从 Open3.popen3 标准输出中提取值的正则表达式 [英] RegEx for extracting a value from Open3.popen3 stdout
问题描述
如何获取外部命令的输出并从中提取值?
How do I get the output of an external command and extract values from it?
我有这样的事情:
stdin, stdout, stderr, wait_thr = Open3.popen3("#{path}/foobar", configfile)
if /exit 0/ =~ wait_thr.value.to_s
runlog.puts("Foobar exited normally.\n")
puts "Test completed."
someoutputvalue = stdout.read("TX.*\s+(\d+)\s+")
puts "Output value: " + someoutputvalue
end
我没有在 stdout 上使用正确的方法,因为 Ruby 告诉我它不能将 String 转换为 Integer.
I'm not using the right method on stdout since Ruby tells me it can't convert String into Integer.
例如,如果输出是
"TX So and so: 28"
我只想得到28
".我验证了上面的正则表达式匹配我需要匹配的内容,我只是想知道如何将提取的值存储在变量中.
I would like to get only "28
". I validated that the regex above matches what I need to match, I'm only wondering how to store that extracted value in a variable.
这样做的正确方法是什么?我在文档中的任何地方都找不到可用于 stdout 的方法.我正在使用 Ruby 1.9.3 中的 stout.read
.
What is the right way of doing this? I can't find anywhere in the documentation the methods available for stdout. I'm using stout.read
from Ruby 1.9.3.
推荐答案
所有需要的信息都在 Popen3 文档,但您必须仔细阅读所有内容并仔细查看示例.您还可以从 流程文档 中收集有用的信息.
All the information needed is in the Popen3 documentation, but you have to read it all and look at the examples pretty carefully. You can also glean useful information from the Process docs too.
也许这会更好地解释它:
Maybe this will 'splain it better:
require 'open3'
captured_stdout = ''
captured_stderr = ''
exit_status = Open3.popen3(ENV, 'date') {|stdin, stdout, stderr, wait_thr|
pid = wait_thr.pid # pid of the started process.
stdin.close
captured_stdout = stdout.read
captured_stderr = stderr.read
wait_thr.value # Process::Status object returned.
}
puts "STDOUT: " + captured_stdout
puts "STDERR: " + captured_stderr
puts "EXIT STATUS: " + (exit_status.success? ? 'succeeded' : 'failed')
运行输出:
STDOUT: Wed Jun 12 07:07:12 MST 2013
STDERR:
EXIT STATUS: succeeded
注意事项:
- 您经常需要
关闭
stdin
流.如果被调用的应用程序需要 STDIN 上的输入,它将挂起直到看到流关闭,然后将继续处理. stdin
、stdout
、stderr
是IO 句柄,所以要阅读IO 类文档 以了解可用的方法.- 您必须使用
puts
、print
或write
和read<输出到
stdin
/code> 或gets
从stdout
和stderr
. exit_status
不是字符串,而是 Process::Status 类的实例.您可以尝试从其to_s
版本进行解析,但不要这样做.而是使用访问器来查看它返回的内容.- 我传入了
ENV
哈希,因此子程序可以访问父程序看到的整个环境.没有必要这样做;相反,如果您不想让孩子访问所有内容,您可以为孩子创建一个简化的环境,或者您可以通过更改值来扰乱其对环境的看法. - 问题中发布的代码
stdout.read("TX.*\s+(\d+)\s+")
是,嗯......废话.我不知道你从哪里得到的,因为在 Ruby 的 IO 类中没有记录 IO#read 或 IO.读取.
- You often have to
close
thestdin
stream. If the called application expects input on STDIN it will hang until it sees the stream close, then will continue its processing. stdin
,stdout
,stderr
are IO handles, so you have to read the IO class documentation to find out what methods are available.- You have to output to
stdin
usingputs
,print
orwrite
, andread
orgets
fromstdout
andstderr
. exit_status
isn't a string, it's an instance of the Process::Status class. You can mess with trying to parse from itsto_s
version, but don't. Instead use the accessors to see what it returned.- I passed in the
ENV
hash, so the child program had access to the entire environment the parent saw. It's not necessary to do that; Instead you can create a reduced environment for the child if you don't want it to have access to everything, or you can mess with its view of the environment by changing values. - The code
stdout.read("TX.*\s+(\d+)\s+")
posted in the question is, um... nonsense. I have no idea where you got that as nothing like that is documented in Ruby's IO class for IO#read or IO.read.
如果不需要写入被调用代码的 STDIN,使用 capture3
会更容易:
It's easier to use capture3
if you don't need to write to STDIN of the called code:
require 'open3'
stdout, stderr, exit_status = Open3.capture3('date')
puts "STDOUT: " + stdout
puts "STDERR: " + stderr
puts "EXIT STATUS: " + (exit_status.success? ? 'succeeded' : 'failed')
输出:
STDOUT: Wed Jun 12 07:23:23 MST 2013
STDERR:
EXIT STATUS: succeeded
使用正则表达式从字符串中提取值是微不足道的,正则表达式文档.从最后一个代码示例开始:
Extracting a value from a string using a regular expression is trivial, and well covered by the Regexp documentation. Starting from the last code example:
stdout[/^\w+ (\w+ \d+) .+ (\d+)$/]
puts "Today is: " + [$1, $2].join(' ')
输出:
Today is: Jun 12 2013
这是使用 字符串.[]
非常灵活的方法.
That's using the String.[]
method which is extremely flexible.
另一种使用命名捕获":
An alternate is using "named captures":
/^\w+ (?<mon_day>\w+ \d+) .+ (?<year>\d+)$/ =~ stdout
puts "Today is: #{ mon_day } #{ year }"
输出相同的东西.命名捕获的缺点是它们速度较慢,我认为这是为了稍微方便.
which outputs the same thing. The downside to named captures is they're slower for what I consider a minor bit of convenience.
"TX So and so: 28"[/\d+$/]
=> "28"
这篇关于用于从 Open3.popen3 标准输出中提取值的正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!