How to create a key value pair from the following data using ruby?
result="-e hostname=webserver001 -e username=root -e password=testing123"
I want to parse it and produce and produce the following output:
{"hostname"=>"webserver001", "username"=>"root", "password"=>"testing123"}
result = "-e hostname=webserver001 -e username=root -e password=testing123"
Code
p result.scan(/\w+=\w+/)
.map { _1.split("=") }
.to_h
Or
p Hash[result.scan(/\w+=\w+/)
.map { _1.split("=") }]
Output
{"hostname"=>"webserver001", "username"=>"root", "password"=>"testing123"}
You can try something like :
result = " -e hostname=webserver001 -e username=root -e password=testing123"
hash = Hash.new
res = result.split(' -e ')
res.each { |x|
if x.split('=').length() > 1
part = x.split('=')
hash[part[0]] = part[1]
end
}
puts hash
Related
I can't get to have the variables in an expect loop written:
#!/bin/bash
expect -c "
set var1 10
puts {$var1}
puts $expect_out({$var1})
foreach name { bob jim jacobo henric } {
puts {hello $name $var1}
}"
my output is:
# ./test
({})
hello
hello
hello
hello
So basically it's not expanding any variable.
Any idea?
You should quote with ', not "! This should get the job done:
#!/bin/bash
expect -c '
set var1 10
puts "$var1"
send_user "Confirm? (Y/n): "
expect_user -re "(.*)\n"
set var1 $expect_out(1,string)
foreach name { bob jim jacobo henric } {
puts "hello $name $var1"
}
'
Output:
10
Confirm? (Y/n): Y
hello bob Y
hello jim Y
hello jacobo Y
hello henric Y
Thanks a lot, it worked as a charm.
But it has some issues when the array elements are passed via parameter like this:
function a {
names=$1
expect -c '
foreach name { $names } {
puts "$name"
}
'
}
It just prints:
$names
you mean that any variable must be wrap around by single and double quotes?
' "$variable" '
ok I decided to put the expect code in a separate script test.ex:
set interfaces [lindex $argv 0]
foreach int { $var} {
puts $int
}
When I call the expect it does not cycle over the strings elements:
test.ex "string1 string2"
as it just prints:
$var
It is just ignoring the variable content, and it handles the variable as a string itself without expanding it, is there a way to get it work?
I figured it out!
Just needed to remove the curly brackets {} around the variable that need to be looped over:
set interfaces [lindex $argv 0]
foreach int $var {
puts $int
}
Here is my full code so far:
if ARGV.size == 0
print "Set a library name as parameter"
else
dir = ARGV[0]
begin
Dir.chdir "#{dir}"
rescue
print "No such library"
else
filelist = Dir.glob "*.rb"
outfile = "result"
i = 0
while i < filelist.size do
filename = filelist[i]
output = load "./#{filename}"
if output == 1
File.open(outfile, 'a+') { |file| file.write("#{filename}")}
end
i += 1
end
end
end
The subscripts I'm trying to run can either contain this: print "1" or this: print "0".
I want to write to a "result" file
filename :: OK
if it is print "1", and
filename :: WRONG
if it is print "2".
My problem is that output always equals true instead of 1 or 0. How could I redirect the subscript's STDOUT to the output variable?
This should give you the output :
output = `ruby #{filename}`
Note : It returns a string, but you are comparing output to a number. Do the necessary conversions.
You can use backticks (``) to run your script and capture its output as a string.
`ruby somescript.rb`
# "1"
A hackier approach, but which actually works with load, is to overwrite $stdout before loading the script.
require 'stringio'
output = StringIO.new
stdout = $stdout
begin
$stdout = output
load 'somescript.rb'
ensure
$stdout = stdout
end
output.string
# "1"
Below is my script that acquire the MAC of the machine and store within a config file.
My problem is that within each line have the character " " and it dont print it inside the file, how can I write the file using " "
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
echo "
view.sslVerificationMode = *3*
view.autoConnectDesktop = *TRUE*
view.autoConnectBroker = *TRUE*
view.kioskLogin = *TRUE*
view.nonInteractive = *TRUE*
view.fullScreen = *TRUE*
view.nomenubar = *TRUE*
view.defaultBroker = *viewcs*
view.defaultUser = *CM-${MAC//:/_}*
" > /etc/vmware/view-mandatory-config;
sed -i 's/*/"/g' /etc/vmware/view-mandatory-config
with cat and a here-doc you can use multi-line input without escaping charaters
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
cat << EOT > /etc/vmware/view-mandatory-config
view.sslVerificationMode = "3"
view.autoConnectDesktop = "TRUE"
view.autoConnectBroker = "TRUE"
view.kioskLogin = "TRUE"
view.nonInteractive = "TRUE"
view.fullScreen = "TRUE"
view.nomenubar = "TRUE"
view.defaultBroker = "viewcs"
view.defaultUser = "CM-${MAC//:/_}"
EOT
cat will relay the stdin input generated by the here document to stdout, thus enabling redirection to a file
Simply escape double-quotes within the outer double-quotes by putting a backslash in front of them:
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
echo "
view.sslVerificationMode = \"3\"
view.autoConnectDesktop = \"TRUE\"
view.autoConnectBroker = \"TRUE\"
view.kioskLogin = \"TRUE\"
view.nonInteractive = \"TRUE\"
view.fullScreen = \"TRUE\"
view.nomenubar = \"TRUE\"
view.defaultBroker = \"viewcs\"
view.defaultUser = \"CM-${MAC//:/_}\"
" > /etc/vmware/view-mandatory-config
f = File.open("/test/serverlist.txt", "r")
list = f.readlines
list.each do|servers|
File.open('/test/results.txt','w') do |b|
servers.each do |p|
r = `ping -n 1 #{p}`
b.puts r
end
end
It reads the serverlist file, and returns a string. The serverlist file contains the following IP addresses:
192.168.150.254
192.168.120.2
Are you looking to read each line from the file and then do something with like this.
fout = File.open('/test/results.txt','w')
File.open("/test/serverlist.txt", "r").each_line do |server|
server.chomp!
r = `ping -n 1 #{server}`
fout.puts r
end
I don't think you will need to iterate over the server line itself, and with a few style mods added and ping(1) arguments changed, I would suggest...
open 'serverlist.txt', 'r' do |f|
open '/tmp/results.txt', 'w' do |b|
f.readlines.each do |server|
b.puts `ping -c 1 -t 1 #{server}`
end
end
end
Just use b.write in place of b.puts
if you're using linux you could just go for
File.open("serverlist.txt").each { |addy| `echo "#{`ping -c 1 #{addy}`}" >> result.txt` }
and be done with it
well .. maybe add
`echo "# server-availability" > result.txt`
before the above line so the file gets reset every time you call this
Since:
irb --help
Usage: irb.rb [options] [programfile] [arguments]
I know I can pass arguments to ARGV if I include a programfile
eg:
irb test.rb A B C
where test.irb is simply "p ARGV"
produces:
["a", "b", "c"]
Making programfile be con in DOS... I can do following
irb con A B C
con(main):001:0> ARGV
produces:
ARGV
=> ["A", "B", "C"]
but this is system dependent and has the side effect of echoing input :-(
What i really like is something like
irb -- a b c
BTW: I know I can set ARGV inside irb but I my intention is to alias special == irb -rSpecialLibrary" so I can do something like:
special A B C
<input goes here>
Any suggestions?
Looking at the source of the irb executable:
#!/usr/bin/env ruby
require "irb"
if __FILE__ == $0
IRB.start(__FILE__)
else
# check -e option
if /^-e$/ =~ $0
IRB.start(__FILE__)
else
IRB.setup(__FILE__)
end
end
The at the source of the IRB module:
# File lib/irb/init.rb, line 15
def IRB.setup(ap_path)
IRB.init_config(ap_path)
IRB.init_error
IRB.parse_opts
IRB.run_config
IRB.load_modules
unless #CONF[:PROMPT][#CONF[:PROMPT_MODE]]
IRB.fail(UndefinedPromptMode, #CONF[:PROMPT_MODE])
end
end
Down to parse_opts, our problem method:
# File lib/irb/init.rb, line 126
def IRB.parse_opts
load_path = []
while opt = ARGV.shift
case opt
when "-f"
#CONF[:RC] = false
when "-m"
#CONF[:MATH_MODE] = true
when "-d"
$DEBUG = true
when /^-r(.+)?/
opt = $1 || ARGV.shift
#CONF[:LOAD_MODULES].push opt if opt
when /^-I(.+)?/
opt = $1 || ARGV.shift
load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
when '-U'
set_encoding("UTF-8", "UTF-8")
when /^-E(.+)?/, /^--encoding(?:=(.+))?/
opt = $1 || ARGV.shift
set_encoding(*opt.split(':', 2))
when "--inspect"
#CONF[:INSPECT_MODE] = true
when "--noinspect"
#CONF[:INSPECT_MODE] = false
when "--readline"
#CONF[:USE_READLINE] = true
when "--noreadline"
#CONF[:USE_READLINE] = false
when "--echo"
#CONF[:ECHO] = true
when "--noecho"
#CONF[:ECHO] = false
when "--verbose"
#CONF[:VERBOSE] = true
when "--noverbose"
#CONF[:VERBOSE] = false
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
opt = $1 || ARGV.shift
prompt_mode = opt.upcase.tr("-", "_").intern
#CONF[:PROMPT_MODE] = prompt_mode
when "--noprompt"
#CONF[:PROMPT_MODE] = :NULL
when "--inf-ruby-mode"
#CONF[:PROMPT_MODE] = :INF_RUBY
when "--sample-book-mode", "--simple-prompt"
#CONF[:PROMPT_MODE] = :SIMPLE
when "--tracer"
#CONF[:USE_TRACER] = true
when /^--back-trace-limit(?:=(.+))?/
#CONF[:BACK_TRACE_LIMIT] = ($1 || ARGV.shift).to_i
when /^--context-mode(?:=(.+))?/
#CONF[:CONTEXT_MODE] = ($1 || ARGV.shift).to_i
when "--single-irb"
#CONF[:SINGLE_IRB] = true
when /^--irb_debug=(?:=(.+))?/
#CONF[:DEBUG_LEVEL] = ($1 || ARGV.shift).to_i
when "-v", "--version"
print IRB.version, "\n"
exit 0
when "-h", "--help"
require "irb/help"
IRB.print_usage
exit 0
when "--"
if opt = ARGV.shfit
#CONF[:SCRIPT] = opt
$0 = opt
end
break
when /^-/
IRB.fail UnrecognizedSwitch, opt
else
#CONF[:SCRIPT] = opt
$0 = opt
break
end
end
if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION
load_path.collect! do |path|
/\A\.\// =~ path ? path : File.expand_path(path)
end
end
$LOAD_PATH.unshift(*load_path)
end
It is hardcoded to take that option as the script name (#CONF[:SCRIPT] = opt). Luckily, this is Ruby. The first idea I had was using a different script to launch IRB that modifies the module first.
~/bin/custom-irb:
#!/usr/bin/env ruby
require 'irb'
module IRB
class << self
# sort of lame way to reset the parts we don't like about
# parse_opts after it does the parts we do like
def parse_opts_with_ignoring_script
arg = ARGV.first
script = $0
parse_opts_without_ignoring_script
#CONF[:SCRIPT] = nil
$0 = script
ARGV.unshift arg
end
alias_method :parse_opts_without_ignoring_script, :parse_opts
alias_method :parse_opts, :parse_opts_with_ignoring_script
end
end
if __FILE__ == $0
IRB.start(__FILE__)
else
# check -e option
if /^-e$/ =~ $0
IRB.start(__FILE__)
else
IRB.setup(__FILE__)
end
end
You can launch this with custom-irb foo bar baz and ARGV will be ['foo', 'bar', 'baz'].
quite strange solution is to create file with variables
# defaults.rb
#a = "hello world"
And
# terminal
=> irb -r defaults.rb
irb=> #a
irb=> "hello world"
You can make a file that modifies ARGV and then use '-r' to include it.
$ echo 'ARGV = ["testing", "1","2","3"]' > ~/blah.rb && irb -r ./blah test.rb
/home/me/blah.rb:1: warning: already initialized constant ARGV
test.rb(main):001:0> require 'pp'
=> true
test.rb(main):002:0* pp ARGV
["testing", "1", "2", "3"]
=> ["testing", "1", "2", "3"]
test.rb(main):003:0>
You could even redirect it to your your ~/.irbrc and leave out the '-r ./blah'.