我正在将 net::ssh
session 的输出发送到 ASA,并尝试为每个 vpn 用户构建一个散列,然后将每个散列添加到一个数组中。
这是连接一个用户时的输出。如果有多个用户,则每个用户有更多这样的行:
Username:arozar
Index:654
AssignedIP:10.254.254.7
PublicIP:4.2.2.2
Protocol:AnyConnect-ParentSSL-TunnelDTLS-Tunnel
License:AnyConnectEssentials
Encryption:AnyConnect-Parent:(1)noneSSL-Tunnel:(1)AES256DTLS-Tunnel:(1)AES256
Hashing:AnyConnect-Parent:(1)noneSSL-Tunnel:(1)SHA1DTLS-Tunnel:(1)SHA1
BytesTx:6104355
BytesRx:1191505
GroupPolicy:vpn
TunnelGroup:anyconnect
LoginTime:08:51:55ESTMonNov32014
Duration:1h:08m:48s
Inactivity:0h:00m:00s
NACResult:Unknown
VLANMapping:N/A
VLAN:none
这是我正在处理的代码:
@ac_array = Array.new
session_output = cmd_session.cmd('show vpn-sessiondb anyconnect')
cmd_session.close
session_output.each_line do |line|
username = line.match(/(?<=Username:)(\w+\S+)/)
assigned_ip = line.match(/(?<=AssignedIP:)(\w+\S+)/)
public_ip = line.match(/(?<=PublicIP:)(\w+\S+)/)
license = line.match(/(?<=License:)(\w+\S+)/)
bytestx = line.match(/(?<=BytesTx:)(\w+\S+)/)
bytesrx = line.match(/(?<=BytesRx:)(\w+\S+)/)
group_policy = line.match(/(?<=GroupPolicy:)(\w+\S+)/)
tunnel_group = line.match(/(?<=TunnelGroup:)(\w+\S+)/)
要将这些匹配放入哈希中,我必须这样做:
unless username.nil?
anyconnect_hash = {username:username[0]}
@ac_array.push(anyconnect_hash)
end
unless assigned_ip.nil?
assigned_ip_hash = {assigned_ip:assigned_ip[0]}
@ac_array.push(assigned_ip_hash)
end
unless public_ip.nil?
public_ip_hash = {public_ip:public_ip[0]}
@ac_array.push(public_ip_hash)
end
AND SO ONE DOWN THE LINE for all the matches.....
但我认为这不是最好的方法,在我看来它也不是真正有效的方法。我喜欢使用一行 unless
语句并将所有匹配项分配给那里的哈希值。
以下是我认为会更好的部分:
unless username.nil? and assigned_ip.nil? and public_ip.nil?
anyconnect_hash = {username:username[0], assigned_ip:assigned_ip[0], public_ip:public_ip[0]}
@ac_array.push(anyconnect_hash)
end
不幸的是,使用此设置我得到“nil:NilClass 的未定义方法‘[]’”。
最佳答案
您可以为每个用户执行以下操作。
代码
ATTRIBUTES = [:Username, :AssignedIP, :PublicIP, :License,
:BytesTx, :BytesRx, :GroupPolicy, :TunnelGroup]
def hashify(text)
text.each_line.with_object({}) do |line, h|
ATTRIBUTES.each do |sym|
v = line[/(?<=#{sym.to_s}:)\w+\S+/]
h[sym] = v if v
end
end
end
示例
text =
"Username:arozar
AssignedIP:10.254.254.7
PublicIP:4.2.2.2
License:AnyConnectEssentials
BytesTx:6104355
BytesRx:1191505
GroupPolicy:vpn
TunnelGroup:anyconnect"
hashify(text)
#=> {:Username=>"arozar", :AssignedIP=>"10.254.254.7", :PublicIP=>"4.2.2.2",
# :License=>"AnyConnectEssentials", :BytesTx=>"6104355",
# :BytesRx=>"1191505", :GroupPolicy=>"vpn", :TunnelGroup=>"anyconnect"}
注意事项
- 如果你真的想要一个散列数组,很容易转换散列 (
hashify(text).to_a.map {|k,v| {k=>v} }
),但是请考虑使用散列是否会更好。这将为您提供每个用户一个散列的数组。我怀疑,更好的办法是为每个用户使用一个包含一个元素的单一散列。对于示例中的用户,该键值对将是:
.
"arozar" => { :AssignedIP=>"10.254.254.7", :PublicIP=>"4.2.2.2",
:License=>"AnyConnectEssentials", :BytesTx=>"6104355",
:BytesRx=>"1191505", :GroupPolicy=>"vpn",
:TunnelGroup=>"anyconnect" }
如果示例中显示的哈希值不是您想要的,您将需要修改
\w+\S+
[此处与(\w+\S+)相同
] 在你的正则表达式中。这使用了方法的形式 String#[]以正则表达式作为参数。
如果您愿意而不是使用正则表达式,您可以编写
k,v = line.split(':'); u = v[/\w+\S+/]; h[sym] = u if u
,但我更喜欢原样。
关于ruby-on-rails - 如何进行多行匹配并将它们分配给哈希?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26721800/