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

Posted

技术标签:

【中文标题】更改 CSV 文本中的数字区域设置格式(在数字中用逗号交换点)【英文标题】:Change number locale format in CSV text (swap dot with comma in numbers) 【发布时间】:2014-03-30 10:06:57 【问题描述】:

我有一个带有逗号分隔字段的文本文件。数字字段值被双引号括起来,格式为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

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

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

如何仅在数字字段中交换点和逗号?

【问题讨论】:

你的例子正确吗?它以"PAGOBANCOMAT 开头,但没有结尾" - 对不起,你是对的。刚刚编辑过该字段的值是:“PAGOBANCOMAT 16/03/14,ORE 11:17,TESS.800999999 FARMACIA XXXYYY DR.ZZZ” 【参考方案1】:

可能不是您期望的答案:您可以一个接一个地进行两个步骤。

在 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 获取 CSV 的指示。谢谢,这很有帮助。【参考方案2】:

我会推荐一种带有真正 CSV 解析器的语言。所以 ruby​​,而不是 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,可以根据需要更新文件。

【讨论】:

以上是关于更改 CSV 文本中的数字区域设置格式(在数字中用逗号交换点)的主要内容,如果未能解决你的问题,请参考以下文章

Win7系统怎么更改日期,时间和数字格式

Powershell 中的 Excel 到 .csv 不断更改日期和长数字的格式

CSV文件保存数字为文本形式后再次打开后数字任然显示为科学计数法的问题?

将数字字符串转换为不同的区域格式

如何强制 Text::CSV 将数字存储为文本?

openpyxl将数字格式设置为单元格但不起作用