Reputation: 107
Newbie learning Ruby.
I am trying to take a txt file and on each line take the first 3 characters and assign them as a key, and the rest of the string as that's keys value.
f = File.open("textfile.txt", "r")
finalHash = {"Key" => "Data"}
lineString = ""
while f.gets != nil do
lineString = f.gets
part1 = lineString.slice(0, 2)
part2 = lineString.slice(3, lineString.length)
finalHash[:part1] = part2
end
puts finalHash
Any advice is appreciated!
Upvotes: 1
Views: 251
Reputation: 7679
Here you go :
Sample data:
[zatcsv]$ cat foo.txt
TOK UPDATE DATE SHOT TIME AUXHEAT PHASE STATE PGASA PGASZ BGASA BGASZ BGASA2 BGASZ2 PIMPA
PIMPZ PELLET RGEO RMAG AMIN SEPLIM XPLIM KAPPA DELTA INDENT AREA VOL CONFIG IGRADB WALMAT DIVMAT LIMMAT EVAP
BT IP VSURF Q95 BEPMHD BETMHD BEPDIA NEL DNELDT ZEFF PRAD POHM ENBI PINJ BSOURCE PINJ2 BSOURCE2 COCTR PNBI ECHFREQ
ECHMODE ECHLOC PECH ICFREQ ICSCHEME ICANTEN PICRH LHFREQ LHNPAR PLH IBWFREQ PIBW TE0 TI0 WFANI WFICRH MEFF ISEQ WTH WTOT
JET 20031201 20001006 53521 1.000E+01 NBIC HSELM TRANS 2.000E+00 1.000E+00 2 1 0 0 1.658E+01 8.152E+00 NONE 2.888E+00
HEEH OIJ OIJJ 3.047E+00 9.807E-01 2.924E-02 7.304E-02 1.572E+00 1.781E-01 0.000E+00 4.572E+00 8.161E+01 LSN 1 IN/
2.000E+06 1.013E-01 6.001E+00 1.053E+00 9.252E-01 1.128E+00 3.106E+19 3.106E+19 6.612E+00 4.515E+06 5.122E+04 1.000E+05 1.466E+07
771706 0.000E+00 652114 1.000E+00 1.420E+07 -9.999E-09 NONE NONE 0.000E+00 5.100E+07 HMIN MONOPOLE 4.027E+06 3.700E+09 1.840E+00
2.000E+06 -9.999E-09 0.000E+00 9.295E+03 1.373E+04 6.913E-01 7.319E+05 2.000E+00 NONE 3.715E+06 5.381E+06 1.282E+06 1.297E+07 1.210E+07
something like this will do it for you :
[za csv]$cat text_to_hash.rb
#!/usr/bin/env ruby
file_dir = "/dir/to_folder/foo.txt"
thehash = Hash.new
line = File.read(file_dir).each_line do |line|
thehash[ key = line.slice(0..2)] = val = line.slice(3..-1)
thehash.each { |k , val| puts " Key: #{key} Value: #{val}"}
end
Outputs:
[za csv]$ ./text_to_hash.rb
Key: TOK Value: UPDATE DATE SHOT TIME AUXHEAT PHASE STATE PGASA PGASZ BGASA BGASZ BGASA2 BGASZ2 PIMPA
Key: PIM Value: PZ PELLET RGEO RMAG AMIN SEPLIM XPLIM KAPPA DELTA INDENT AREA VOL CONFIG IGRADB WALMAT DIVMAT LIMMAT EVAP
Key: ECH Value: MODE ECHLOC PECH ICFREQ ICSCHEME ICANTEN PICRH LHFREQ LHNPAR PLH IBWFREQ PIBW TE0 TI0 WFANI WFICRH MEFF ISEQ WTH WTOT
Key: JET Value: 20031201 20001006 53521 1.000E+01 NBIC HSELM TRANS 2.000E+00 1.000E+00 2 1 0 0 1.658E+01 8.152E+00 NONE 2.888E+00
Key: HEE Value: H OIJ OIJJ 3.047E+00 9.807E-01 2.924E-02 7.304E-02 1.572E+00 1.781E-01 0.000E+00 4.572E+00 8.161E+01 LSN 1 IN/
Key: 2.0 Value: 00E+06 1.013E-01 6.001E+00 1.053E+00 9.252E-01 1.128E+00 3.106E+19 3.106E+19 6.612E+00 4.515E+06 5.122E+04 1.000E+05 1.466E+07
Key: 771 Value: 706 0.000E+00 652114 1.000E+00 1.420E+07 -9.999E-09 NONE NONE 0.000E+00 5.100E+07 HMIN MONOPOLE 4.027E+06 3.700E+09 1.840E+00
Key: 2.0 Value: 00E+06 -9.999E-09 0.000E+00 9.295E+03 1.373E+04 6.913E-01 7.319E+05 2.000E+00 NONE 3.715E+06 5.381E+06 1.282E+06 1.297E+07 1.210E+07
Key: 4.4 Value: 45E-01 2.194E-01
Upvotes: 0
Reputation: 110665
Let's first create a file:
text = <<_
Now is the
time for all
good Rubiests
to come to the
aid of their
bowling team.
_
FName = 'temp'
File.write(FName, text)
#=> 80
Now read the file a line at a time and construct the desired hash:
File.foreach(FName).with_object({}) do |line, h|
h[line.slice!(0,3)] = line.chomp
end
#=> {"Now"=>" is the", "tim"=>"e for all", "goo"=>"d Rubiests",
# "to "=>"come to the", "aid"=>" of their", "bow"=>"ling team."}
After reading the first line,
h = { "Now"=>" is the" }
line = "time for all\n"
a = line.chomp
#=> "time for all"
b = a.slice!(0,3)
#=> "tim"
a #=> "e for all"
h[b] = a
#=> "e for all"
h #=> {"Now"=>" is the", "tim"=>"e for all"}
No direction is given if a line contains fewer than three characters. That may be something to consider.
Upvotes: 1
Reputation: 304127
Borrowing @Cary's sample file...
text = <<_
Now is the
time for all
good Rubiests
to come to the
aid of their
bowling team.
_
FName = 'temp'
File.write(FName, text)
Now the file exists. Convert it to a 2 dimensional array. This array is trivially converted to a hash
File.foreach(FName).map{|x| [x.slice!(0,3), x]}.to_h
=> {"Now"=>" is the\n", "tim"=>"e for all\n", "goo"=>"d Rubiests\n", "to "=>"come to the\n", "aid"=>" of their\n", "bow"=>"ling team.\n"}
Upvotes: 0
Reputation: 39695
lines = File.open("textfile.txt").read.split("\n")
hsh = {}
lines.each do |line|
next if line == ""
hsh[line[0..2]] = line[3..-1]
end
using your method of slowly nibbling at the file
f = File.open("textfile.txt")
hsh = {}
loop do
x = f.gets
break unless x
hsh[x[0..2]] = x[3..-1]
end
Upvotes: 0
Reputation: 19237
the 2nd parameter of slice is the length, not the end-index, so change:
part1 = lineString.slice(0, 2)
to:
part1 = lineString.slice(0, 3)
If passed a start index and a length, returns a substring containing length characters starting at the index
Also you don't need the second parameter here (this is not a bug though):
part2 = lineString.slice(3, lineString.length)
This is enough:
part2 = lineString.slice(3)
Upvotes: 1