我有一个文本文件:
GLKIIM 08052016 08052016 444-22222222 33333 5675555
ABCDEF 87645123 34211016 333-11111111 22222 5123455
我正在使用CSV.read
来阅读文本文件。
对于文本文件中的每一行,我需要通过开始和结束位置提取列值。为此,我有阵列:
start_pos = [1 8 17 26 30 39 45]
end_pos = [6 15 24 28 37 43 51]
表示从位置start_pos[0]
到end_pos[0]
的文本文件,即1到6,我们将拥有第一列的值GLKIIM
和{{1} }。
列名是:
ABCDEF
我需要创建一个哈希,如下所示:
column_name = [SOURCE_NAME BATCH_DATE EFFECT_DATE ID ACCOUNT_NO ENTITY ACCOUNT]
我不能使用空格({
0=>{"SOURCE_NAME"=>"GLKIIM", "BATCH_DATE"=>"08052016", "EFFECT_DATE"=>"08052016", "ID"=>"444", "ACCOUNT_NO"=>"22222222", "ENTITY"=>"33333", "ACCOUNT"=>"5675555"},
1=>{"SOURCE_NAME"=>"ABCDEF", "BATCH_DATE"=>"87645123", "EFFECT_DATE"=>"34211016", "ID"=>"333", "ACCOUNT_NO"=>"11111111", "ENTITY"=>"22222", "ACCOUNT"=>"5123455"}
}
)作为分隔符来分隔列值,我需要使用开始和结束位置。
答案 0 :(得分:1)
不要将文件作为逗号分隔值(CSV)文件读取,如果它不是。
使用"说代码"您可以使用File.readlines
代替:
#!/bin/env ruby
result = ARGF.readlines.map do |line|
[line[0..5], line[7..14], line[16..23], line[24..36]]
end
puts result.inspect
# => [["GLKIIM", "08052016", "08052016", " 444-22222222"], ["ABCDEF", "87645123", "34211016", " 333-11111111"]]
如果您保存此脚本,则可以将其运行为:
readliner.rb MYFILE.TXT MYFILE2.TXT MYFILE3.TXT
或管道:
cat myfile | readliner.rb
或者使用
File.readlines("MYFILE.TXT")
脚本中的而不是ARGF.readlines
。
readlines
的使用可能会带来问题,因为它将整个文件读入内存以产生一系列行。有关该主题的小型讨论,请参阅评论。
让代码高尔夫一点,同时保持一定的可读性并删除readlines
:
#!/bin/env ruby
COLS = { "SOURCE_NAME" => 0..5,
"BATCH_DATE" => 7..14,
"EFFECT_DATE" => 16..23 }
result = ARGF.each_with_index.map do |line, idx|
[idx, COLS.map{|name,range| [name, line[range]] }.to_h ]
end.to_h
puts result.inspect
# => {0=>{"SOURCE_NAME"=>"GLKIIM", "BATCH_DATE"=>"08052016", "EFFECT_DATE"=>"08052016"}, 1=>{"SOURCE_NAME"=>"ABCDEF", "BATCH_DATE"=>"87645123", "EFFECT_DATE"=>"34211016"}}
答案 1 :(得分:1)
input = 'GLKIIM 08052016 08052016 444-22222222 33333 5675555
ABCDEF 87645123 34211016 333-11111111 22222 5123455'
start_pos = %w|1 8 17 26 30 39 45|.map &:to_i
end_pos = %w|6 15 24 28 37 43 51|.map &:to_i
input.split($/).map do |line|
start_pos.zip(end_pos).map { |s, e| line[s-1..e-1] }
end
#⇒ [["GLKIIM", "08052016", "08052016", "444", "22222222", "33333", "5675555"],
# ["ABCDEF", "87645123", "34211016", "333", "11111111", "22222", "5123455"]]
答案 2 :(得分:0)
我使用下面的代码:
file = File.open('abc.TXT', "r")
i = 0
file.each_line do |line|
temp = {}
for itrator in 0..column_name.length-1
temp[column_name[itrator]] = line[start_pos[itrator]-1..end_pos[itrator]-1]
end
data_hash[i] = temp
i+=1
end
puts data_hash
假设包含以下数据的文件名为abc.txt
:
GLKIIM 08052016 08052016 444-22222222 33333 5675555
ABCDEF 87645123 34211016 333-11111111 22222 5123455