更改CSV文本中的数字区域设置格式(交换点以逗号表示)

时间:2014-03-30 10:06:58

标签: ruby regex sed formatting number-formatting

我有一个带逗号分隔字段的文本文件。数字字段值是双引号,并在Italian locale中格式化为"4.294.967.295,000"。以下是文本文件中的示例数据:

Saldo contabile:,"1.123.456,89"
Saldo disponibile:,"1.123.456,89"

18/03/2014,16/03/2014,"-22,00","-23.122,00",EUR,AUT,-,43,PDPOT,"PAGOBANCOMAT            16/03/14,ORE 11:17,TESS.800999999                 FARMACIA XXXYYY DR.ZZZ",-

1

我希望通过将"4,294,967,295.00"","交换,将格式更改为美国英语区域设置,例如".",最好使用sed,vim或Ruby。交换点和逗号不是解决方案,因为逗号也用作字段之间的分隔符。

到目前为止I was able to match fields需要进行替换: sample regexp to match numeric fields

如何只在数字字段内交换点和逗号?

2 个答案:

答案 0 :(得分:3)

可能不是你期望的答案:你可以一个接一个地做两个步骤。

在Ruby中:s.gsub('.','').gsub(',','.')

This action could be integrated in a CSV-parser.

示例:

require 'csv'
data = <<data
Saldo contabile:,"1.123.456,89"
Saldo disponibile:,"1.123.456,89"
Saldo disponibile:,"-1.123.456,89"
data
CSV::Converters[:num_it] = ->(s) {(s =~ /[-\d\.,]+/) ? (s.gsub('.','').gsub(',','.').to_f) : s}
#Alternative version with String#tr
#CSV::Converters[:num_it] = ->(s) {(s =~ /[-\d\.,]+/) ? (s.tr('.,', '_.').to_f) : s}
csv = CSV(data, :headers => false, :col_sep => ',',
                #~ :converters => :all
                :converters => [
                    *CSV::Converters.keys,
                    :num_it
                ]
            )
csv.each do |row|
  #~ p row
  print row[0];print " %.2f\n" % row[1]
end

结果:

Saldo contabile: 1123456.89
Saldo disponibile: 1123456.89
Saldo disponibile: -1123456.89

除了包含两个sub的版本,您还可以尝试一个String#gsub with the hash or block-version

s = "1.123.456,89"
p s.gsub(/[\.,]/, {'.' => ',', ',' => '.'}) #-> "1,123,456.89"
p s.gsub(/[\.,]/){|hit| hit == '.' ?  ',' : '.'} #-> "1,123,456.89"

答案 1 :(得分:1)

我建议使用带有真正CSV解析器的语言。所以红宝石,不是awk:

echo 'Saldo contabile:,"1.123.456,89"
Saldo disponibile:,"1.123.456,89"'|
ruby -rcsv -ne '
  row = CSV.parse_line($_)
  row.each {|elem| elem.tr!(",.",".,") if elem.match(/^-?[0-9,.]+$/)} 
  puts CSV.generate_line(row)
'
Saldo contabile:,"1,123,456.89"
Saldo disponibile:,"1,123,456.89"

Ruby有一个-i选项,就像sed -i一样,可以根据需要更新文件。