我有一个带逗号分隔字段的文本文件。数字字段值是双引号,并在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需要进行替换:
如何只在数字字段内交换点和逗号?
答案 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
一样,可以根据需要更新文件。