我想读取一个在远程服务器上具有名称值对的文件。根据我的要求,我需要shell到远程服务器,读取文件,然后grep的值。例如:
/domain/srvr/primary = ABC
/host/DEF/second = DEF
/host/XYZ/second = XYZ
/host/GHI/second = GHI
:
:
:
现在我想读取这个文件,并创建一个包含所有辅助服务器的数组(例如:DEF,XYZ,GHI),但我的值是零。
primary = @ssh.exec!("cd /home/dir; grep 'srvr/primary' #{filename} | awk '{print $3}'")
secondary = @ssh.exec!("cd /home/dir; grep '\<host.*second\>' #{filename} | awk '{print $3}'")`
它正确打印主服务器名称,但对辅助服务器阵列返回nil。我尝试使用split("\n")
,但错误地说undefined method 'split' for nil:NilClass
。
需要帮助才能获得阵列中的所有辅助服务器。
答案 0 :(得分:0)
你可以使用这样的东西
file_contents.
split("\n").
map {|line| line.split(" = ") }.
find_all {|pair| pair[0] =~ /second$/ }.
map(&:last)
并且可能使用cat
获取文件内容或通过ssh下载文件。如果在同一台服务器中,只需使用File.read
。
如果你只能使用bash或只是喜欢,你可以使用
grep -p "^\/host.*second" path/to/file | cut -d" " -f 3
-p
选项将在grep
上启用perl regexp语法,它将为您提供搜索文件所需的所有功能。然后cut
将按分隔符-d
拆分每个字符串。获取基于1的索引-f
的字段。在这种情况下string = server
,server
位于第三个字段。
答案 1 :(得分:0)
您可以简化任务并仅抓取数据并在本地处理数据,而不是尝试在远程主机上执行工作。您可以使用Net::SCP(docs),Net::FTP或Net::SFTP轻松检索数据。
在收到文字后,我会使用这样的内容来获取所需的数据:
data = <<EOT
/domain/srvr/primary = ABC
/host/DEF/second = DEF
/host/XYZ/second = XYZ
/host/GHI/second = GHI
EOT
data.split("\n").grep(/\bsecond\b/).map{ |l| l.split.last }
# => ["DEF", "XYZ", "GHI"]
或:
data.split("\n").grep(/\bsecond\b/).map{ |l| l[/= (\S+)/, 1] }
# => ["DEF", "XYZ", "GHI"]
或:
data.split("\n").grep(/\bsecond\b/).map{ |l| l.rstrip[/\S+$/] }
# => ["DEF", "XYZ", "GHI"]
只是为了让它变得更有趣:
require 'fruity'
data = <<EOT
/domain/srvr/primary = ABC
/host/DEF/second = DEF
/host/XYZ/second = XYZ
/host/GHI/second = GHI
EOT
compare do
p1 { data.split("\n").grep(/\bsecond\b/).map{ |l| l[/= (\S+)/, 1] } }
p2 { data.split("\n").grep(/\bsecond\b/).map{ |l| l.rstrip[/\S+$/] } }
p3 { data.split("\n").grep(/\bsecond\b/).map{ |l| l.rstrip[/\S+$/] } }
end
# >> Running each test 256 times. Test will take about 1 second.
# >> p1 is faster than p2 by 3.9x ± 0.01
# >> p2 is similar to p3